Merge pull request #738 from aleksijuvani/curl-update

Update curl to 7.53.1
This commit is contained in:
Tom van Dijck 2017-04-24 12:58:34 -07:00 committed by GitHub
commit 97856fe923
205 changed files with 8818 additions and 6375 deletions

View File

@ -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.

View File

@ -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.
@ -133,7 +143,7 @@ struct curl_httppost {
char *buffer; /* pointer to allocated buffer contents */
long bufferlength; /* length of buffer field */
char *contenttype; /* Content-Type */
struct curl_slist* contentheader; /* list of extra headers for this form */
struct curl_slist *contentheader; /* list of extra headers for this form */
struct curl_httppost *more; /* if one field name has more than one
file, this link should link to following
files */
@ -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.
@ -260,7 +275,7 @@ struct curl_fileinfo {
unsigned int flags;
/* used internally */
char * b_data;
char *b_data;
size_t b_size;
size_t b_used;
};
@ -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()

View File

@ -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

View File

@ -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
@ -58,7 +58,7 @@ CURL_EXTERN CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...);
* curl_easy_duphandle() for each new thread to avoid a series of identical
* curl_easy_setopt() invokes in every thread.
*/
CURL_EXTERN CURL* curl_easy_duphandle(CURL *curl);
CURL_EXTERN CURL *curl_easy_duphandle(CURL *curl);
/*
* NAME curl_easy_reset()

View File

@ -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

View File

@ -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
@ -24,8 +24,8 @@
#include <sys/types.h>
size_t fread (void *, size_t, size_t, FILE *);
size_t fwrite (const void *, size_t, size_t, FILE *);
size_t fread(void *, size_t, size_t, FILE *);
size_t fwrite(const void *, size_t, size_t, FILE *);
int strcasecmp(const char *, const char *);
int strncasecmp(const char *, const char *, size_t);

View File

@ -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
@ -40,7 +40,7 @@
*/
#define curl_easy_setopt(handle, option, value) \
__extension__ ({ \
__typeof__ (option) _curl_opt = option; \
__typeof__(option) _curl_opt = option; \
if(__builtin_constant_p(_curl_opt)) { \
if(_curl_is_long_option(_curl_opt)) \
if(!_curl_is_long(value)) \
@ -110,7 +110,7 @@ __extension__ ({ \
/* FIXME: don't allow const pointers */
#define curl_easy_getinfo(handle, info, arg) \
__extension__ ({ \
__typeof__ (info) _curl_info = info; \
__typeof__(info) _curl_info = info; \
if(__builtin_constant_p(_curl_info)) { \
if(_curl_is_string_info(_curl_info)) \
if(!_curl_is_arr((arg), char *)) \
@ -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 || \
@ -363,7 +365,7 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
/* XXX: should evaluate to true iff expr is a pointer */
#define _curl_is_any_ptr(expr) \
(sizeof(expr) == sizeof(void*))
(sizeof(expr) == sizeof(void *))
/* evaluates to true if expr is NULL */
/* XXX: must not evaluate expr, so this check is not accurate */
@ -455,12 +457,12 @@ _CURL_WARNING(_curl_easy_getinfo_err_curl_slist,
_curl_callback_compatible((expr), _curl_read_callback4) || \
_curl_callback_compatible((expr), _curl_read_callback5) || \
_curl_callback_compatible((expr), _curl_read_callback6))
typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void*);
typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void*);
typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE*);
typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void*);
typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void*);
typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
typedef size_t (_curl_read_callback1)(char *, size_t, size_t, void *);
typedef size_t (_curl_read_callback2)(char *, size_t, size_t, const void *);
typedef size_t (_curl_read_callback3)(char *, size_t, size_t, FILE *);
typedef size_t (_curl_read_callback4)(void *, size_t, size_t, void *);
typedef size_t (_curl_read_callback5)(void *, size_t, size_t, const void *);
typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE *);
/* evaluates to true if expr is of type curl_write_callback or "similar" */
#define _curl_is_write_cb(expr) \
@ -473,14 +475,14 @@ typedef size_t (_curl_read_callback6)(void *, size_t, size_t, FILE*);
_curl_callback_compatible((expr), _curl_write_callback4) || \
_curl_callback_compatible((expr), _curl_write_callback5) || \
_curl_callback_compatible((expr), _curl_write_callback6))
typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void*);
typedef size_t (_curl_write_callback1)(const char *, size_t, size_t, void *);
typedef size_t (_curl_write_callback2)(const char *, size_t, size_t,
const void*);
typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE*);
typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void*);
const void *);
typedef size_t (_curl_write_callback3)(const char *, size_t, size_t, FILE *);
typedef size_t (_curl_write_callback4)(const void *, size_t, size_t, void *);
typedef size_t (_curl_write_callback5)(const void *, size_t, size_t,
const void*);
typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
const void *);
typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE *);
/* evaluates to true if expr is of type curl_ioctl_callback or "similar" */
#define _curl_is_ioctl_cb(expr) \
@ -490,10 +492,10 @@ typedef size_t (_curl_write_callback6)(const void *, size_t, size_t, FILE*);
_curl_callback_compatible((expr), _curl_ioctl_callback2) || \
_curl_callback_compatible((expr), _curl_ioctl_callback3) || \
_curl_callback_compatible((expr), _curl_ioctl_callback4))
typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void*);
typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void*);
typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void*);
typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void*);
typedef curlioerr (_curl_ioctl_callback1)(CURL *, int, void *);
typedef curlioerr (_curl_ioctl_callback2)(CURL *, int, const void *);
typedef curlioerr (_curl_ioctl_callback3)(CURL *, curliocmd, void *);
typedef curlioerr (_curl_ioctl_callback4)(CURL *, curliocmd, const void *);
/* evaluates to true if expr is of type curl_sockopt_callback or "similar" */
#define _curl_is_sockopt_cb(expr) \

View File

@ -4,7 +4,6 @@
*.orig
*.rej
*.res
Makefile.vc*.dist
TAGS
curl_config.h
curl_config.h.in

View File

@ -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 "")

View File

@ -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 \

View File

@ -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

View File

@ -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)"

View File

@ -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

View File

@ -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.

View File

@ -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;

View File

@ -169,7 +169,7 @@ int Curl_resolver_duphandle(void **to, void *from)
return CURLE_OK;
}
static void destroy_async_data (struct Curl_async *async);
static void destroy_async_data(struct Curl_async *async);
/*
* Cancel all possibly still on-going resolves for this connection.
@ -184,7 +184,7 @@ void Curl_resolver_cancel(struct connectdata *conn)
/*
* destroy_async_data() cleans up async resolver data.
*/
static void destroy_async_data (struct Curl_async *async)
static void destroy_async_data(struct Curl_async *async)
{
free(async->hostname);
@ -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)

View File

@ -155,8 +155,8 @@ struct thread_sync_data {
curl_mutex_t * mtx;
int done;
char * hostname; /* hostname to resolve, Curl_async.hostname
duplicate */
char *hostname; /* hostname to resolve, Curl_async.hostname
duplicate */
int port;
int sock_error;
Curl_addrinfo *res;
@ -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;
};
@ -200,7 +200,7 @@ void destroy_thread_sync_data(struct thread_sync_data * tsd)
/* Initialize resolver thread synchronization data */
static
int init_thread_sync_data(struct thread_data * td,
const char * hostname,
const char *hostname,
int port,
const struct addrinfo *hints)
{
@ -263,7 +263,7 @@ static int getaddrinfo_complete(struct connectdata *conn)
* For builds without ARES, but with ENABLE_IPV6, create a resolver thread
* and wait on it.
*/
static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
static unsigned int CURL_STDCALL getaddrinfo_thread(void *arg)
{
struct thread_sync_data *tsd = (struct thread_sync_data*)arg;
struct thread_data *td = tsd->td;
@ -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) {
@ -300,7 +303,7 @@ static unsigned int CURL_STDCALL getaddrinfo_thread (void *arg)
/*
* gethostbyname_thread() resolves a name and then exits.
*/
static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
static unsigned int CURL_STDCALL gethostbyname_thread(void *arg)
{
struct thread_sync_data *tsd = (struct thread_sync_data *)arg;
struct thread_data *td = tsd->td;
@ -333,7 +336,7 @@ static unsigned int CURL_STDCALL gethostbyname_thread (void *arg)
/*
* destroy_async_data() cleans up async resolver data and thread handle.
*/
static void destroy_async_data (struct Curl_async *async)
static void destroy_async_data(struct Curl_async *async)
{
if(async->os_specific) {
struct thread_data *td = (struct thread_data*) async->os_specific;
@ -372,14 +375,14 @@ static void destroy_async_data (struct Curl_async *async)
*
* Returns FALSE in case of failure, otherwise TRUE.
*/
static bool init_resolve_thread (struct connectdata *conn,
const char *hostname, int port,
const struct addrinfo *hints)
static bool init_resolve_thread(struct connectdata *conn,
const char *hostname, int port,
const struct addrinfo *hints)
{
struct thread_data *td = calloc(1, sizeof(struct thread_data));
int err = RESOLVER_ENOMEM;
conn->async.os_specific = (void*) td;
conn->async.os_specific = (void *)td;
if(!td)
goto err_exit;
@ -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 */
@ -609,10 +613,13 @@ Curl_addrinfo *Curl_resolver_getaddrinfo(struct connectdata *conn,
#ifdef CURLRES_IPV6
/* check if this is an IPv6 address string */
if(Curl_inet_pton (AF_INET6, hostname, &in6) > 0)
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;

View File

@ -27,7 +27,7 @@
struct addrinfo;
struct hostent;
struct SessionHandle;
struct Curl_easy;
struct connectdata;
struct Curl_dns_entry;

View File

@ -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)
{

View File

@ -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;
}

View File

@ -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"

View File

@ -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
@ -676,7 +676,7 @@
/*#define RANDOM_FILE "/dev/urandom"*/
#define RECV_TYPE_ARG1 int
#define RECV_TYPE_ARG2 void*
#define RECV_TYPE_ARG2 void *
#define RECV_TYPE_ARG3 size_t
#define RECV_TYPE_ARG4 int
#define RECV_TYPE_RETV ssize_t
@ -692,7 +692,7 @@
#define SEND_TYPE_ARG1 int
#define SEND_QUAL_ARG2 const
#define SEND_TYPE_ARG2 void*
#define SEND_TYPE_ARG2 void *
#define SEND_TYPE_ARG3 size_t
#define SEND_TYPE_ARG4 int
#define SEND_TYPE_RETV ssize_t

View File

@ -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) {

View File

@ -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,
struct timeval *nowp,
bool duringconnect)
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 */
@ -193,7 +194,7 @@ long Curl_timeleft(struct SessionHandle *data,
if(duringconnect && (data->set.connecttimeout > 0))
timeout_set |= 2;
switch (timeout_set) {
switch(timeout_set) {
case 1:
timeout_ms = data->set.timeout;
break;
@ -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,26 +601,28 @@ 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;
}
/* retrieves ip address and port from a sockaddr structure */
static bool getaddressinfo(struct sockaddr* sa, char* addr,
long* port)
static bool getaddressinfo(struct sockaddr *sa, char *addr,
long *port)
{
unsigned short us_port;
struct sockaddr_in* si = NULL;
struct sockaddr_in *si = NULL;
#ifdef ENABLE_IPV6
struct sockaddr_in6* si6 = NULL;
struct sockaddr_in6 *si6 = NULL;
#endif
#if defined(HAVE_SYS_UN_H) && defined(AF_UNIX)
struct sockaddr_un* su = NULL;
struct sockaddr_un *su = NULL;
#endif
switch (sa->sa_family) {
switch(sa->sa_family) {
case AF_INET:
si = (struct sockaddr_in*)(void*) sa;
si = (struct sockaddr_in *)(void *) sa;
if(Curl_inet_ntop(sa->sa_family, &si->sin_addr,
addr, MAX_IPADR_LEN)) {
us_port = ntohs(si->sin_port);
@ -629,7 +632,7 @@ static bool getaddressinfo(struct sockaddr* sa, char* addr,
break;
#ifdef ENABLE_IPV6
case AF_INET6:
si6 = (struct sockaddr_in6*)(void*) sa;
si6 = (struct sockaddr_in6 *)(void *) sa;
if(Curl_inet_ntop(sa->sa_family, &si6->sin6_addr,
addr, MAX_IPADR_LEN)) {
us_port = ntohs(si6->sin6_port);
@ -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;
@ -842,7 +845,7 @@ CURLcode Curl_is_connected(struct connectdata *conn,
if(result) {
/* no more addresses to try */
const char* hostname;
const char *hostname;
/* if the first address family runs out of addresses to try before
the happy eyeball timeout, go ahead and try the next family now */
@ -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,7 +1088,10 @@ static CURLcode singleipconnect(struct connectdata *conn,
CONNECT_RESUME_ON_READ_WRITE | CONNECT_DATA_IDEMPOTENT,
NULL, 0, NULL, NULL);
#elif defined(MSG_FASTOPEN) /* Linux */
rc = 0; /* Do nothing */
if(conn->given->flags & PROTOPT_SSL)
rc = connect(sockfd, &addr.sa_addr, addr.addrlen);
else
rc = 0; /* Do nothing */
#endif
}
else {
@ -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));
}

View File

@ -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,9 +35,9 @@ 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,
struct timeval *nowp,
bool duringconnect);
time_t Curl_timeleft(struct Curl_easy *data,
struct timeval *nowp,
bool duringconnect);
#define DEFAULT_CONNECT_TIMEOUT 300000 /* milliseconds == five minutes */
#define HAPPY_EYEBALLS_TIMEOUT 200 /* milliseconds to wait between
@ -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 */

View File

@ -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,13 +67,13 @@ 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);
failf(data, "Error while processing content unencoding: %s",
z->msg);
else
failf (data, "Error while processing content unencoding: "
"Unknown failure within decompression software.");
failf(data, "Error while processing content unencoding: "
"Unknown failure within decompression software.");
return CURLE_BAD_CONTENT_ENCODING;
}
@ -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
@ -327,14 +327,14 @@ Curl_unencode_gzip_write(struct connectdata *conn,
* can handle the gzip header themselves.
*/
switch (k->zlib_init) {
switch(k->zlib_init) {
/* Skip over gzip header? */
case ZLIB_INIT:
{
/* Initial call state */
ssize_t hlen;
switch (check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
switch(check_gzip_header((unsigned char *)k->str, nread, &hlen)) {
case GZIP_OK:
z->next_in = (Bytef *)k->str + hlen;
z->avail_in = (uInt)(nread - hlen);
@ -371,18 +371,15 @@ 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 */
memcpy(z->next_in + z->avail_in - nread, k->str, nread);
switch (check_gzip_header(z->next_in, z->avail_in, &hlen)) {
switch(check_gzip_header(z->next_in, z->avail_in, &hlen)) {
case GZIP_OK:
/* This is the zlib stream data */
free(z->next_in);
@ -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)

View File

@ -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 '.'.
@ -147,12 +146,12 @@ static bool tailmatch(const char *cooke_domain, const char *hostname)
* matching cookie path and url path
* RFC6265 5.1.4 Paths and Path-Match
*/
static bool pathmatch(const char* cookie_path, const char* request_uri)
static bool pathmatch(const char *cookie_path, const char *request_uri)
{
size_t cookie_path_len;
size_t uri_path_len;
char* uri_path = NULL;
char* pos;
char *uri_path = NULL;
char *pos;
bool ret = FALSE;
/* cookie_path must not have last '/' separator. ex: /sample */
@ -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 && !strcasecompare("localhost", whatptr))
domain=":";
}
#endif
/* check for more dots */
dotp = strchr(whatptr, '.');
if(!dotp)
domain=":";
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! */
freecookie(co);
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;
@ -1314,7 +1371,7 @@ static int cookie_output(struct CookieInfo *c, const char *dumphere)
fprintf(out, "#\n# Fatal libcurl error\n");
if(!use_stdout)
fclose(out);
return 1;
return 1;
}
fprintf(out, "%s\n", format_ptr);
free(format_ptr);
@ -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) {

View File

@ -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 */

View File

@ -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);
@ -286,21 +291,24 @@ Curl_he2ai(const struct hostent *he, int port)
size_t ss_size;
#ifdef ENABLE_IPV6
if(he->h_addrtype == AF_INET6)
ss_size = sizeof (struct sockaddr_in6);
ss_size = sizeof(struct sockaddr_in6);
else
#endif
ss_size = sizeof (struct sockaddr_in);
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);
@ -325,7 +333,7 @@ Curl_he2ai(const struct hostent *he, int port)
/* leave the rest of the struct filled with zero */
switch (ai->ai_family) {
switch(ai->ai_family) {
case AF_INET:
addr = (void *)ai->ai_addr; /* storage area for this info */
@ -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

View File

@ -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 */

View File

@ -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);

View File

@ -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 */

View File

@ -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:
*

View File

@ -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) |

View File

@ -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

View File

@ -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 */
@ -59,7 +59,7 @@ int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
#else
int err;
char* dot;
char *dot;
#ifdef DEBUGBUILD

View File

@ -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,
@ -94,7 +94,7 @@ static size_t display_gss_error(OM_uint32 status, int type,
if(GSS_LOG_BUFFER_LEN > len + status_string.length + 3) {
len += snprintf(buf + len, GSS_LOG_BUFFER_LEN - len,
"%.*s. ", (int)status_string.length,
(char*)status_string.value);
(char *)status_string.value);
}
gss_release_buffer(&min_stat, &status_string);
} while(!GSS_ERROR(maj_stat) && msg_ctx != 0);
@ -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];

View File

@ -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 */

View File

@ -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
@ -24,11 +24,11 @@
#ifndef CURL_DISABLE_CRYPTO_AUTH
typedef void (* HMAC_hinit_func)(void * context);
typedef void (* HMAC_hupdate_func)(void * context,
const unsigned char * data,
typedef void (* HMAC_hinit_func)(void *context);
typedef void (* HMAC_hupdate_func)(void *context,
const unsigned char *data,
unsigned int len);
typedef void (* HMAC_hfinal_func)(unsigned char * result, void * context);
typedef void (* HMAC_hfinal_func)(unsigned char *result, void *context);
/* Per-hash function HMAC parameters. */
@ -46,21 +46,21 @@ typedef struct {
/* HMAC computation context. */
typedef struct {
const HMAC_params * hmac_hash; /* Hash function definition. */
void * hmac_hashctxt1; /* Hash function context 1. */
void * hmac_hashctxt2; /* Hash function context 2. */
const HMAC_params *hmac_hash; /* Hash function definition. */
void *hmac_hashctxt1; /* Hash function context 1. */
void *hmac_hashctxt2; /* Hash function context 2. */
} HMAC_context;
/* Prototypes. */
HMAC_context * Curl_HMAC_init(const HMAC_params * hashparams,
const unsigned char * key,
HMAC_context * Curl_HMAC_init(const HMAC_params *hashparams,
const unsigned char *key,
unsigned int keylen);
int Curl_HMAC_update(HMAC_context * context,
const unsigned char * data,
int Curl_HMAC_update(HMAC_context *context,
const unsigned char *data,
unsigned int len);
int Curl_HMAC_final(HMAC_context * context, unsigned char * result);
int Curl_HMAC_final(HMAC_context *context, unsigned char *result);
#endif

View File

@ -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 */)
{
@ -541,8 +566,10 @@ CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
gcry_md_hd_t MD4pw;
gcry_md_open(&MD4pw, GCRY_MD_MD4, 0);
gcry_md_write(MD4pw, pw, 2 * len);
memcpy (ntbuffer, gcry_md_read (MD4pw, 0), MD4_DIGEST_LENGTH);
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);

View File

@ -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 */);

View File

@ -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;
}

View File

@ -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,17 +255,20 @@ 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] :
sasl->params->service;
const char *service = data->set.str[STRING_SERVICE_NAME] ?
data->set.str[STRING_SERVICE_NAME] :
sasl->params->service;
#endif
sasl->force_ir = force_ir; /* Latch for future use */
@ -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);

View File

@ -24,7 +24,7 @@
#include <curl/curl.h>
struct SessionHandle;
struct Curl_easy;
struct connectdata;
/* Authentication mechanism flags */

View File

@ -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
@ -30,8 +30,8 @@ struct Curl_sec_client_mech {
void (*end)(void *);
int (*check_prot)(void *, int);
int (*overhead)(void *, int, int);
int (*encode)(void *, const void*, int, int, void**);
int (*decode)(void *, void*, int, int, struct connectdata *);
int (*encode)(void *, const void *, int, int, void **);
int (*decode)(void *, void *, int, int, struct connectdata *);
};
#define AUTH_OK 0
@ -39,11 +39,11 @@ struct Curl_sec_client_mech {
#define AUTH_ERROR 2
#ifdef HAVE_GSSAPI
int Curl_sec_read_msg (struct connectdata *conn, char *,
enum protection_level);
void Curl_sec_end (struct connectdata *);
CURLcode Curl_sec_login (struct connectdata *);
int Curl_sec_request_prot (struct connectdata *conn, const char *level);
int Curl_sec_read_msg(struct connectdata *conn, char *,
enum protection_level);
void Curl_sec_end(struct connectdata *);
CURLcode Curl_sec_login(struct connectdata *);
int Curl_sec_request_prot(struct connectdata *conn, const char *level);
extern struct Curl_sec_client_mech Curl_krb5_client_mech;
#endif

View File

@ -233,6 +233,15 @@
# include "setup-vms.h"
#endif
/*
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
* interface doesnt 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,
@ -470,8 +479,8 @@
# ifdef __minix
/* Minix 3 versions up to at least 3.1.3 are missing these prototypes */
extern char * strtok_r(char *s, const char *delim, char **last);
extern struct tm * gmtime_r(const time_t * const timep, struct tm *tmp);
extern char *strtok_r(char *s, const char *delim, char **last);
extern struct tm *gmtime_r(const time_t * const timep, struct tm *tmp);
# endif
# define DIR_CHAR "/"
@ -602,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
@ -641,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
@ -749,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 */

View File

@ -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) {

View File

@ -59,7 +59,7 @@ static void *curl_thread_create_thunk(void *arg)
return 0;
}
curl_thread_t Curl_thread_create(unsigned int (*func) (void*), void *arg)
curl_thread_t Curl_thread_create(unsigned int (*func) (void *), void *arg)
{
curl_thread_t t = malloc(sizeof(pthread_t));
struct curl_actual_call *ac = malloc(sizeof(struct curl_actual_call));
@ -100,7 +100,8 @@ int Curl_thread_join(curl_thread_t *hnd)
#elif defined(USE_THREADS_WIN32)
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
/* !checksrc! disable SPACEBEFOREPAREN 1 */
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
void *arg)
{
#ifdef _WIN32_WCE

View File

@ -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,7 +50,8 @@
#if defined(USE_THREADS_POSIX) || defined(USE_THREADS_WIN32)
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void*),
/* !checksrc! disable SPACEBEFOREPAREN 1 */
curl_thread_t Curl_thread_create(unsigned int (CURL_STDCALL *func) (void *),
void *arg);
void Curl_thread_destroy(curl_thread_t hnd);

View File

@ -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

View File

@ -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) {

View File

@ -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)

View File

@ -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 */

View File

@ -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"
@ -42,7 +43,7 @@
*/
static bool Curl_isunreserved(unsigned char in)
{
switch (in) {
switch(in) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
case 'a': case 'b': case 'c': case 'd': case 'e':
@ -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;
size_t inputlen = length;
size_t outputlen;
CURLcode res = Curl_urldecode(handle, string, inputlen, &str, &outputlen,
FALSE);
if(res)
return NULL;
if(olen)
*olen = curlx_uztosi(outputlen);
if(length >= 0) {
size_t inputlen = length;
size_t outputlen;
CURLcode res = Curl_urldecode(data, string, inputlen, &str, &outputlen,
FALSE);
if(res)
return NULL;
if(olen) {
if(outputlen <= (size_t) INT_MAX)
*olen = curlx_uztosi(outputlen);
else
/* too large to return in an int, fail! */
Curl_safefree(str);
}
}
return str;
}

View File

@ -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);

View File

@ -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,14 +306,14 @@ 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;
curl_off_t bytecount = 0;
struct timeval now = Curl_tvnow();
struct_stat file_stat;
const char* buf2;
const char *buf2;
/*
* Since FILE: doesn't do the full init, we need to provide some extra
@ -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)

View File

@ -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. */
@ -80,7 +81,7 @@ AddHttpPost(char *name, size_t namelength,
char *buffer, size_t bufferlength,
char *contenttype,
long flags,
struct curl_slist* contentHeader,
struct curl_slist *contentHeader,
char *showfilename, char *userp,
struct curl_httppost *parent_post,
struct curl_httppost **httppost,
@ -201,9 +202,9 @@ static const char *ContentTypeForFilename(const char *filename,
if(filename) { /* in case a NULL was passed in */
for(i=0; i<sizeof(ctts)/sizeof(ctts[0]); i++) {
if(strlen(filename) >= strlen(ctts[i].extension)) {
if(strequal(filename +
strlen(filename) - strlen(ctts[i].extension),
ctts[i].extension)) {
if(strcasecompare(filename +
strlen(filename) - strlen(ctts[i].extension),
ctts[i].extension)) {
contenttype = ctts[i].type;
break;
}
@ -315,7 +316,7 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
break;
}
switch (option) {
switch(option) {
case CURLFORM_ARRAY:
if(array_state)
/* we don't support an array from within an array */
@ -547,9 +548,9 @@ CURLFORMcode FormAdd(struct curl_httppost **httppost,
{
/* this "cast increases required alignment of target type" but
we consider it OK anyway */
struct curl_slist* list = array_state?
(struct curl_slist*)(void*)array_value:
va_arg(params, struct curl_slist*);
struct curl_slist *list = array_state?
(struct curl_slist *)(void *)array_value:
va_arg(params, struct curl_slist *);
if(current_form->contentheader)
return_value = CURL_FORMADD_OPTION_TWICE;
@ -761,8 +762,8 @@ CURLFORMcode curl_formadd(struct curl_httppost **httppost,
* and CD/DVD images should be either a STREAM_LF format or a fixed format.
*
*/
curl_off_t VmsRealFileSize(const char * name,
const struct_stat * stat_buf)
curl_off_t VmsRealFileSize(const char *name,
const struct_stat *stat_buf)
{
char buffer[8192];
curl_off_t count;
@ -791,8 +792,8 @@ curl_off_t VmsRealFileSize(const char * name,
* if not to call a routine to get the correct size.
*
*/
static curl_off_t VmsSpecialSize(const char * name,
const struct_stat * stat_buf)
static curl_off_t VmsSpecialSize(const char *name,
const struct_stat *stat_buf)
{
switch(stat_buf->st_fab_rfm) {
case FAB$C_VAR:
@ -845,16 +846,23 @@ static CURLcode AddFormData(struct FormData **formp,
goto error;
}
#endif
if(type != FORM_DATAMEM) {
newform->line = malloc((size_t)length+1);
if(!newform->line) {
result = CURLE_OUT_OF_MEMORY;
goto error;
}
alloc2 = newform->line;
memcpy(newform->line, line, (size_t)length);
newform->line = malloc((size_t)length+1);
if(!newform->line) {
result = CURLE_OUT_OF_MEMORY;
goto error;
/* zero terminate for easier debugging */
newform->line[(size_t)length]=0;
}
else {
newform->line = (char *)line;
type = FORM_DATA; /* in all other aspects this is just FORM_DATA */
}
alloc2 = newform->line;
memcpy(newform->line, line, (size_t)length);
newform->length = (size_t)length;
newform->line[(size_t)length]=0; /* zero terminate for easier debugging */
}
else
/* For callbacks and files we don't have any actual data so we just keep a
@ -863,13 +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,
@ -1150,7 +1167,7 @@ CURLcode Curl_getformdata(struct SessionHandle *data,
curl_off_t size = 0; /* support potentially ENORMOUS formposts */
char *boundary;
char *fileboundary = NULL;
struct curl_slist* curList;
struct curl_slist *curList;
*finalform = NULL; /* default form is empty */
@ -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,13 +1427,14 @@ 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;
result = stat(file, &statbuf);
switch (statbuf.st_fab_rfm) {
switch(statbuf.st_fab_rfm) {
case FAB$C_VAR:
case FAB$C_VFC:
case FAB$C_STMCR:
@ -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 */

View File

@ -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
@ -64,13 +65,13 @@ typedef struct FormInfo {
file name will be used */
bool showfilename_alloc;
char *userp; /* pointer for the read callback */
struct curl_slist* contentheader;
struct curl_slist *contentheader;
struct FormInfo *more;
} 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 */

View File

@ -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;
@ -455,7 +455,7 @@ static CURLcode ReceivedServerConnect(struct connectdata *conn, bool *received)
result = Curl_socket_check(ctrl_sock, data_sock, CURL_SOCKET_BAD, 0);
/* see if the connection request is already here */
switch (result) {
switch(result) {
case -1: /* error */
/* let's die here */
failf(data, "Error while waiting for server connect");
@ -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
@ -1043,30 +1044,35 @@ static CURLcode ftp_state_use_port(struct connectdata *conn,
if(*string_ftpport == ':') {
/* :port */
ip_end = string_ftpport;
}
else if((ip_end = strchr(string_ftpport, ':')) != NULL) {
/* either ipv6 or (ipv4|domain|interface):port(-range) */
#ifdef ENABLE_IPV6
if(Curl_inet_pton(AF_INET6, string_ftpport, sa6) == 1) {
/* ipv6 */
port_min = port_max = 0;
strcpy(addr, string_ftpport);
ip_end = NULL; /* this got no port ! */
}
else
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) {
/* ipv6 */
port_min = port_max = 0;
strcpy(addr, string_ftpport);
ip_end = NULL; /* this got no port ! */
}
else
#endif
/* (ipv4|domain|interface):port(-range) */
strncpy(addr, string_ftpport, ip_end - ip_start);
}
else
/* ipv4|interface */
strcpy(addr, string_ftpport);
/* (ipv4|domain|interface):port(-range) */
strncpy(addr, string_ftpport, ip_end - ip_start);
}
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;
if(!result)
/* get the "raw" path */
result = Curl_urldecode(data, path_to_use, 0, &path, NULL, FALSE);
if(result) {
/* We can limp along anyway (and should try to since we may already be in
* the error path) */
ftpc->ctl_valid = FALSE; /* mark control connection as bad */
connclose(conn, "FTP: out of memory!"); /* mark for connection closure */
ftpc->prevpath = NULL; /* no path remembering */
@ -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 */
@ -3942,7 +3880,7 @@ static CURLcode wc_statemach(struct connectdata *conn)
struct WildcardData * const wildcard = &(conn->data->wildcard);
CURLcode result = CURLE_OK;
switch (wildcard->state) {
switch(wildcard->state) {
case CURLWC_INIT:
result = init_wc_data(conn);
if(wildcard->state == CURLWC_CLEAN)
@ -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;
@ -4574,7 +4508,7 @@ static CURLcode ftp_setup_connection(struct connectdata *conn)
command = Curl_raw_toupper(type[6]);
conn->bits.type_set = TRUE;
switch (command) {
switch(command) {
case 'A': /* ASCII mode */
data->set.prefer_ascii = TRUE;
break;

View File

@ -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;
@ -143,7 +143,7 @@ struct ftp_conn {
ftpstate state_saved; /* transfer type saved to be reloaded after
data connection is established */
curl_off_t retr_size_saved; /* Size of retrieved file saved */
char * server_os; /* The target server operating system. */
char *server_os; /* The target server operating system. */
curl_off_t known_filesize; /* file size is different from -1, if wildcard
LIST parsing was done and wc_statemach set
it */

View File

@ -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"
@ -397,9 +396,9 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
}
}
switch (parser->os_type) {
switch(parser->os_type) {
case OS_TYPE_UNIX:
switch (parser->state.UNIX.main) {
switch(parser->state.UNIX.main) {
case PL_UNIX_TOTALSIZE:
switch(parser->state.UNIX.sub.total_dirsize) {
case PL_UNIX_TOTALSIZE_INIT:
@ -448,7 +447,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
}
break;
case PL_UNIX_FILETYPE:
switch (c) {
switch(c) {
case '-':
finfo->filetype = CURLFILETYPE_FILE;
break;
@ -968,7 +967,7 @@ size_t Curl_ftp_parselist(char *buffer, size_t size, size_t nmemb,
}
break;
case PL_WINNT_FILENAME:
switch (parser->state.NT.sub.filename) {
switch(parser->state.NT.sub.filename) {
case PL_WINNT_FILENAME_PRESPACE:
if(c != ' ') {
parser->item_offset = finfo->b_used -1;

View File

@ -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

View File

@ -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;

View File

@ -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 */

View File

@ -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,14 +139,18 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
Wait a while for the socket to be writable. Note that this doesn't
acknowledge the timeout.
*/
Curl_socket_ready(CURL_SOCKET_BAD, sockfd, 100);
if(SOCKET_WRITABLE(sockfd, 100) < 0) {
result = CURLE_SEND_ERROR;
break;
}
}
free(sel_org);
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
save allocing another string/doing another _write loop. */
result = Curl_sendf(sockfd, conn, "\r\n");
if(!result)
/* We can use Curl_sendf to send the terminal \r\n relatively safely and
save allocing another string/doing another _write loop. */
result = Curl_sendf(sockfd, conn, "\r\n");
if(result) {
failf(data, "Failed sending Gopher request");
return result;

View File

@ -135,7 +135,7 @@ Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p)
{
struct curl_hash_element *he;
struct curl_llist_element *le;
struct curl_llist *l = FETCH_LIST (h, key, key_len);
struct curl_llist *l = FETCH_LIST(h, key, key_len);
for(le = l->head; le; le = le->next) {
he = (struct curl_hash_element *) le->ptr;
@ -291,9 +291,9 @@ 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_hash_str(void *key, size_t key_length, size_t slots_num)
{
const char* key_str = (const char *) key;
const char *key_str = (const char *) key;
const char *end = key_str + key_length;
unsigned long h = 5381;

View File

@ -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
@ -29,16 +29,16 @@
#include "llist.h"
/* Hash function prototype */
typedef size_t (*hash_function) (void* key,
typedef size_t (*hash_function) (void *key,
size_t key_length,
size_t slots_num);
/*
Comparator function prototype. Compares two keys.
*/
typedef size_t (*comp_function) (void* key1,
typedef size_t (*comp_function) (void *key1,
size_t key1_len,
void*key2,
void *key2,
size_t key2_len);
typedef void (*curl_hash_dtor)(void *);
@ -76,7 +76,7 @@ int Curl_hash_init(struct curl_hash *h,
void *Curl_hash_add(struct curl_hash *h, void *key, size_t key_len, void *p);
int Curl_hash_delete(struct curl_hash *h, void *key, size_t key_len);
void *Curl_hash_pick(struct curl_hash *, void * key, size_t key_len);
void *Curl_hash_pick(struct curl_hash *, void *key, size_t key_len);
void Curl_hash_apply(struct curl_hash *h, void *user,
void (*cb)(void *user, void *ptr));
int Curl_hash_count(struct curl_hash *h);
@ -84,10 +84,9 @@ void Curl_hash_destroy(struct curl_hash *h);
void Curl_hash_clean(struct curl_hash *h);
void Curl_hash_clean_with_criterium(struct curl_hash *h, void *user,
int (*comp)(void *, void *));
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 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 *

View File

@ -49,12 +49,12 @@ static const unsigned char hmac_opad = 0x5C;
HMAC_context *
Curl_HMAC_init(const HMAC_params * hashparams,
const unsigned char * key,
const unsigned char *key,
unsigned int keylen)
{
size_t i;
HMAC_context * ctxt;
unsigned char * hkey;
HMAC_context *ctxt;
unsigned char *hkey;
unsigned char b;
/* Create HMAC context. */
@ -101,7 +101,7 @@ Curl_HMAC_init(const HMAC_params * hashparams,
}
int Curl_HMAC_update(HMAC_context * ctxt,
const unsigned char * data,
const unsigned char *data,
unsigned int len)
{
/* Update first hash calculation. */
@ -110,7 +110,7 @@ int Curl_HMAC_update(HMAC_context * ctxt,
}
int Curl_HMAC_final(HMAC_context * ctxt, unsigned char * result)
int Curl_HMAC_final(HMAC_context *ctxt, unsigned char *result)
{
const HMAC_params * hashparams = ctxt->hmac_hash;

View File

@ -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);

View File

@ -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 */

View File

@ -172,7 +172,7 @@ Curl_printable_address(const Curl_addrinfo *ai, char *buf, size_t bufsize)
const struct in6_addr *ipaddr6;
#endif
switch (ai->ai_family) {
switch(ai->ai_family) {
case AF_INET:
sa4 = (const void *)ai->ai_addr;
ipaddr4 = &sa4->sin_addr;
@ -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];

View File

@ -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,10 +128,10 @@ 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);
int Curl_num_addresses(const Curl_addrinfo *addr);
#if defined(CURLDEBUG) && defined(HAVE_GETNAMEINFO)
int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
@ -143,7 +143,7 @@ int curl_dogetnameinfo(GETNAMEINFO_QUAL_ARG1 GETNAMEINFO_TYPE_ARG1 sa,
#endif
/* IPv4 threadsafe resolve function used for synch and asynch builds */
Curl_addrinfo *Curl_ipv4_resolve_r(const char * hostname, int port);
Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname, int port);
CURLcode Curl_async_resolved(struct connectdata *conn,
bool *protocol_connect);
@ -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 */

View File

@ -291,7 +291,7 @@ Curl_addrinfo *Curl_ipv4_resolve_r(const char *hostname,
* gethostbyname() is the preferred one.
*/
else {
h = gethostbyname((void*)hostname);
h = gethostbyname((void *)hostname);
#endif /* HAVE_GETADDRINFO_THREADSAFE || HAVE_GETHOSTBYNAME_R */
}

View File

@ -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;

View File

@ -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;

View File

@ -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;
@ -545,8 +546,8 @@ CURLcode Curl_http_auth_act(struct connectdata *conn)
}
}
if(http_should_fail(conn)) {
failf (data, "The requested URL returned error: %d",
data->req.httpcode);
failf(data, "The requested URL returned error: %d",
data->req.httpcode);
result = CURLE_HTTP_RETURNED_ERROR;
}
@ -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,23 +785,27 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
while(*auth) {
#ifdef USE_SPNEGO
if(checkprefix("Negotiate", auth)) {
*availp |= CURLAUTH_NEGOTIATE;
authp->avail |= CURLAUTH_NEGOTIATE;
if((authp->avail & CURLAUTH_NEGOTIATE) ||
Curl_auth_is_spnego_supported()) {
*availp |= CURLAUTH_NEGOTIATE;
authp->avail |= CURLAUTH_NEGOTIATE;
if(authp->picked == CURLAUTH_NEGOTIATE) {
if(negdata->state == GSS_AUTHSENT || negdata->state == GSS_AUTHNONE) {
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
if(!result) {
DEBUGASSERT(!data->req.newurl);
data->req.newurl = strdup(data->change.url);
if(!data->req.newurl)
return CURLE_OUT_OF_MEMORY;
data->state.authproblem = FALSE;
/* we received a GSS auth token and we dealt with it fine */
negdata->state = GSS_AUTHRECV;
if(authp->picked == CURLAUTH_NEGOTIATE) {
if(negdata->state == GSS_AUTHSENT ||
negdata->state == GSS_AUTHNONE) {
CURLcode result = Curl_input_negotiate(conn, proxy, auth);
if(!result) {
DEBUGASSERT(!data->req.newurl);
data->req.newurl = strdup(data->change.url);
if(!data->req.newurl)
return CURLE_OUT_OF_MEMORY;
data->state.authproblem = FALSE;
/* we received a GSS auth token and we dealt with it fine */
negdata->state = GSS_AUTHRECV;
}
else
data->state.authproblem = TRUE;
}
else
data->state.authproblem = TRUE;
}
}
}
@ -809,39 +814,46 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
#ifdef USE_NTLM
/* NTLM support requires the SSL crypto libs */
if(checkprefix("NTLM", auth)) {
*availp |= CURLAUTH_NTLM;
authp->avail |= CURLAUTH_NTLM;
if(authp->picked == CURLAUTH_NTLM ||
authp->picked == CURLAUTH_NTLM_WB) {
/* NTLM authentication is picked and activated */
CURLcode result = Curl_input_ntlm(conn, proxy, auth);
if(!result) {
data->state.authproblem = FALSE;
#ifdef NTLM_WB_ENABLED
if(authp->picked == CURLAUTH_NTLM_WB) {
*availp &= ~CURLAUTH_NTLM;
authp->avail &= ~CURLAUTH_NTLM;
*availp |= CURLAUTH_NTLM_WB;
authp->avail |= CURLAUTH_NTLM_WB;
if((authp->avail & CURLAUTH_NTLM) ||
(authp->avail & CURLAUTH_NTLM_WB) ||
Curl_auth_is_ntlm_supported()) {
*availp |= CURLAUTH_NTLM;
authp->avail |= CURLAUTH_NTLM;
/* Get the challenge-message which will be passed to
* ntlm_auth for generating the type 3 message later */
while(*auth && ISSPACE(*auth))
auth++;
if(checkprefix("NTLM", auth)) {
auth += strlen("NTLM");
if(authp->picked == CURLAUTH_NTLM ||
authp->picked == CURLAUTH_NTLM_WB) {
/* NTLM authentication is picked and activated */
CURLcode result = Curl_input_ntlm(conn, proxy, auth);
if(!result) {
data->state.authproblem = FALSE;
#ifdef NTLM_WB_ENABLED
if(authp->picked == CURLAUTH_NTLM_WB) {
*availp &= ~CURLAUTH_NTLM;
authp->avail &= ~CURLAUTH_NTLM;
*availp |= CURLAUTH_NTLM_WB;
authp->avail |= CURLAUTH_NTLM_WB;
/* Get the challenge-message which will be passed to
* ntlm_auth for generating the type 3 message later */
while(*auth && ISSPACE(*auth))
auth++;
if(*auth)
if((conn->challenge_header = strdup(auth)) == NULL)
return CURLE_OUT_OF_MEMORY;
if(checkprefix("NTLM", auth)) {
auth += strlen("NTLM");
while(*auth && ISSPACE(*auth))
auth++;
if(*auth) {
conn->challenge_header = strdup(auth);
if(!conn->challenge_header)
return CURLE_OUT_OF_MEMORY;
}
}
}
}
#endif
}
else {
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
else {
infof(data, "Authentication problem. Ignoring this.\n");
data->state.authproblem = TRUE;
}
}
}
}
@ -849,18 +861,18 @@ CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
#endif
#ifndef CURL_DISABLE_CRYPTO_AUTH
if(checkprefix("Digest", auth)) {
if((authp->avail & CURLAUTH_DIGEST) != 0) {
if((authp->avail & CURLAUTH_DIGEST) != 0)
infof(data, "Ignoring duplicate digest auth header.\n");
}
else {
else if(Curl_auth_is_digest_supported()) {
CURLcode result;
*availp |= CURLAUTH_DIGEST;
authp->avail |= CURLAUTH_DIGEST;
/* We call this function on input Digest headers even if Digest
* authentication isn't activated yet, as we need to store the
* incoming data from this header in case we are gonna use
* Digest. */
* incoming data from this header in case we are going to use
* Digest */
result = Curl_input_digest(conn, proxy, auth);
if(result) {
infof(data, "Authentication problem. Ignoring this.\n");
@ -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,47 +1923,42 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
}
#endif
if(conn->httpversion == 20)
/* In HTTP2 forbids Transfer-Encoding: chunked */
ptr = NULL;
ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
if(ptr) {
/* Some kind of TE is requested, check if 'chunked' is chosen */
data->req.upload_chunky =
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
}
else {
ptr = Curl_checkheaders(conn, "Transfer-Encoding:");
if(ptr) {
/* Some kind of TE is requested, check if 'chunked' is chosen */
data->req.upload_chunky =
Curl_compareheader(ptr, "Transfer-Encoding:", "chunked");
}
else {
if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
data->set.upload &&
(data->state.infilesize == -1)) {
if(conn->bits.authneg)
/* don't enable chunked during auth neg */
;
else if(use_http_1_1plus(data, conn)) {
/* HTTP, upload, unknown file size and not HTTP 1.0 */
data->req.upload_chunky = TRUE;
}
else {
failf(data, "Chunky upload is not supported by HTTP 1.0");
return CURLE_UPLOAD_FAILED;
}
if((conn->handler->protocol&PROTO_FAMILY_HTTP) &&
data->set.upload &&
(data->state.infilesize == -1)) {
if(conn->bits.authneg)
/* don't enable chunked during auth neg */
;
else if(use_http_1_1plus(data, conn)) {
/* HTTP, upload, unknown file size and not HTTP 1.0 */
data->req.upload_chunky = TRUE;
}
else {
/* else, no chunky upload */
data->req.upload_chunky = FALSE;
failf(data, "Chunky upload is not supported by HTTP 1.0");
return CURLE_UPLOAD_FAILED;
}
if(data->req.upload_chunky)
te = "Transfer-Encoding: chunked\r\n";
}
else {
/* else, no chunky upload */
data->req.upload_chunky = FALSE;
}
if(data->req.upload_chunky)
te = "Transfer-Encoding: chunked\r\n";
}
Curl_safefree(conn->allocptr.host);
ptr = Curl_checkheaders(conn, "Host:");
if(ptr && (!data->state.this_is_a_follow ||
Curl_raw_equal(data->state.first_host, conn->host.name))) {
strcasecompare(data->state.first_host, conn->host.name))) {
#if !defined(CURL_DISABLE_COOKIES)
/* If we have a given custom Host: header, we extract the host name in
order to possibly use it for cookie reasons later on. We only allow the
@ -2106,7 +2078,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
/* when doing ftp, append ;type=<a|i> if not present */
char *type = strstr(ppath, ";type=");
if(type && type[6] && type[7] == 0) {
switch (Curl_raw_toupper(type[6])) {
switch(Curl_raw_toupper(type[6])) {
case 'A':
case 'D':
case 'I':
@ -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
);
@ -2337,7 +2312,7 @@ CURLcode Curl_http(struct connectdata *conn, bool *done)
* Free proxyuserpwd for Negotiate/NTLM. Cannot reuse as it is associated
* with the connection and shouldn't be repeated over it either.
*/
switch (data->state.authproxy.picked) {
switch(data->state.authproxy.picked) {
case CURLAUTH_NEGOTIATE:
case CURLAUTH_NTLM:
case CURLAUTH_NTLM_WB:
@ -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;
@ -2786,7 +2766,7 @@ checkhttpprefix(struct SessionHandle *data,
/* convert from the network encoding using a scratch area */
char *scratch = strdup(s);
if(NULL == scratch) {
failf (data, "Failed to allocate memory for conversion!");
failf(data, "Failed to allocate memory for conversion!");
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
}
if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
@ -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)
{
@ -2824,7 +2804,7 @@ checkrtspprefix(struct SessionHandle *data,
/* convert from the network encoding using a scratch area */
char *scratch = strdup(s);
if(NULL == scratch) {
failf (data, "Failed to allocate memory for conversion!");
failf(data, "Failed to allocate memory for conversion!");
return FALSE; /* can't return CURLE_OUT_OF_MEMORY so return FALSE */
}
if(CURLE_OK != Curl_convert_from_network(data, scratch, strlen(s)+1)) {
@ -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)
{
@ -2876,8 +2856,8 @@ static CURLcode header_append(struct SessionHandle *data,
/* The reason to have a max limit for this is to avoid the risk of a bad
server feeding libcurl with a never-ending header that will cause
reallocs infinitely */
failf (data, "Avoided giant realloc for header (max is %d)!",
CURL_MAX_HTTP_HEADER);
failf(data, "Avoided giant realloc for header (max is %d)!",
CURL_MAX_HTTP_HEADER);
return CURLE_OUT_OF_MEMORY;
}
@ -2885,7 +2865,7 @@ static CURLcode header_append(struct SessionHandle *data,
hbufp_index = k->hbufp - data->state.headerbuff;
newbuff = realloc(data->state.headerbuff, newsize);
if(!newbuff) {
failf (data, "Failed to alloc memory for big header!");
failf(data, "Failed to alloc memory for big header!");
return CURLE_OUT_OF_MEMORY;
}
data->state.headersize=newsize;
@ -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,21 +3020,21 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
#endif /* CURL_DOES_CONVERSIONS */
if(100 <= k->httpcode && 199 >= k->httpcode) {
/*
* We have made a HTTP PUT or POST and this is 1.1-lingo
* that tells us that the server is OK with this and ready
* to receive the data.
* However, we'll get more headers now so we must get
* back into the header-parsing state!
*/
k->header = TRUE;
k->headerline = 0; /* restart the header line counter */
/* "A user agent MAY ignore unexpected 1xx status responses." */
switch(k->httpcode) {
case 100:
/*
* We have made a HTTP PUT or POST and this is 1.1-lingo
* that tells us that the server is OK with this and ready
* to receive the data.
* However, we'll get more headers now so we must get
* back into the header-parsing state!
*/
k->header = TRUE;
k->headerline = 0; /* restart the header line counter */
/* if we did wait for this do enable write now! */
if(k->exp100) {
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");
}
}
@ -3113,8 +3106,8 @@ CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
* up and return an error.
*/
if(http_should_fail(conn)) {
failf (data, "The requested URL returned error: %d",
k->httpcode);
failf(data, "The requested URL returned error: %d",
k->httpcode);
return CURLE_HTTP_RETURNED_ERROR;
}
@ -3138,52 +3131,59 @@ 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. */
result = Curl_http_auth_act(conn);
/* 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. */
result = Curl_http_auth_act(conn);
if(result)
return result;
if(result)
return result;
if(k->httpcode >= 300) {
if((!conn->bits.authneg) && !conn->bits.close &&
!conn->bits.rewindaftersend) {
/*
* General treatment of errors when about to send data. Including :
* "417 Expectation Failed", while waiting for 100-continue.
*
* The check for close above is done simply because of something
* else has already deemed the connection to get closed then
* something else should've considered the big picture and we
* avoid this check.
*
* rewindaftersend indicates that something has told libcurl to
* continue sending even if it gets discarded
if(k->httpcode >= 300) {
if((!conn->bits.authneg) && !conn->bits.close &&
!conn->bits.rewindaftersend) {
/*
* General treatment of errors when about to send data. Including :
* "417 Expectation Failed", while waiting for 100-continue.
*
* The check for close above is done simply because of something
* else has already deemed the connection to get closed then
* something else should've considered the big picture and we
* avoid this check.
*
* rewindaftersend indicates that something has told libcurl to
* continue sending even if it gets discarded
*/
switch(data->set.httpreq) {
case HTTPREQ_PUT:
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
/* We got an error response. If this happened before the whole
* request body has been sent we stop sending and mark the
* connection for closure after we've read the entire response.
*/
switch(data->set.httpreq) {
case HTTPREQ_PUT:
case HTTPREQ_POST:
case HTTPREQ_POST_FORM:
/* We got an error response. If this happened before the whole
* request body has been sent we stop sending and mark the
* connection for closure after we've read the entire response.
*/
if(!k->upload_done) {
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;
}
break;
default: /* default label present to avoid compiler warnings */
break;
}
}
@ -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

View File

@ -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);

View File

@ -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,8 +98,9 @@ static int http2_perform_getsock(const struct connectdata *conn,
because of renegotiation. */
sock[0] = conn->sock[FIRSTSOCKET];
if(nghttp2_session_want_read(c->h2))
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
/* in a HTTP/2 connection we can basically always get a frame so we should
always be ready for one */
bitmap |= GETSOCK_READSOCK(FIRSTSOCKET);
if(nghttp2_session_want_write(c->h2))
bitmap |= GETSOCK_WRITESOCK(FIRSTSOCKET);
@ -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,
stream->push_headers_alloc * sizeof(char *));
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;
stream->upload_left -= nread;
if(data_s->state.infilesize != -1)
stream->upload_left -= nread;
}
if(stream->upload_left == 0)
*data_flags = 1;
*data_flags = NGHTTP2_DATA_FLAG_EOF;
else if(nread == 0)
return NGHTTP2_ERR_DEFERRED;
@ -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);
!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)
{
@ -1513,7 +1675,7 @@ static ssize_t http2_send(struct connectdata *conn, int sockindex,
size_t nheader;
size_t i;
size_t authority_idx;
char *hdbuf = (char*)mem;
char *hdbuf = (char *)mem;
char *end, *line_end;
nghttp2_data_provider data_prd;
int32_t stream_id;
@ -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,38 +1843,28 @@ 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;
}
nva[i].flags = NGHTTP2_NV_FLAG_NONE;
if(HEADER_OVERFLOW(nva[i])) {
failf(conn->data, "Failed sending HTTP request: Header overflow");
goto fail;
}
++i;
}
/* :authority must come before non-pseudo header fields */
@ -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);
"headers exceeds %zu bytes and that could cause the "
"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,7 +2086,8 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
" after upgrade: len=%zu\n",
nread);
memcpy(httpc->inbuf, mem, nread);
if(nread)
memcpy(httpc->inbuf, mem, nread);
httpc->inbuflen = nread;
nproc = nghttp2_session_mem_recv(httpc->h2, (const uint8_t *)httpc->inbuf,
@ -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. */

View File

@ -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 */

View File

@ -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;
@ -190,8 +190,8 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
/* Write the data portion available */
#ifdef HAVE_LIBZ
switch (conn->data->set.http_ce_skip?
IDENTITY : data->req.auto_decoding) {
switch(conn->data->set.http_ce_skip?
IDENTITY : data->req.auto_decoding) {
case IDENTITY:
#endif
if(!k->ignorebody) {
@ -219,10 +219,10 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
break;
default:
failf (conn->data,
"Unrecognized content encoding type. "
"libcurl understands `identity', `deflate' and `gzip' "
"content encodings.");
failf(conn->data,
"Unrecognized content encoding type. "
"libcurl understands `identity', `deflate' and `gzip' "
"content encodings.");
return CHUNKE_BAD_ENCODING;
}
#endif
@ -360,7 +360,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
const char *Curl_chunked_strerror(CHUNKcode code)
{
switch (code) {
switch(code) {
default:
return "OK";
case CHUNKE_TOO_LONG_HEX:

View File

@ -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)) {
size_t urilen = tmp - (char *)uripath;
path = (unsigned char *) aprintf("%.*s", urilen, uripath);
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);

View File

@ -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

View File

@ -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);

View File

@ -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 */

View File

@ -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;
}

View File

@ -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 {
@ -258,13 +309,22 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
char *ptr;
char *line_start;
ptr=data->state.buffer;
ptr = data->state.buffer;
line_start = ptr;
nread=0;
perline=0;
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,254 +333,233 @@ 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 */
error = SELECT_ERROR;
failf(data, "Proxy CONNECT aborted due to select/poll error");
/* 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;
}
continue;
}
else if(result) {
keepon = FALSE;
break;
case 0: /* timeout */
}
else if(gotbytes <= 0) {
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 */
conn->bits.proxy_connect_closed = TRUE;
infof(data, "Proxy CONNECT connection closed\n");
}
else {
error = SELECT_ERROR;
failf(data, "Proxy CONNECT aborted");
}
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 */
conn->bits.proxy_connect_closed = TRUE;
infof(data, "Proxy CONNECT connection closed\n");
}
else {
error = SELECT_ERROR;
failf(data, "Proxy CONNECT aborted");
}
/* We got a byte of data */
nread++;
if(keepon > TRUE) {
/* This means we are currently ignoring a response-body */
nread = 0; /* make next read start over in the read buffer */
ptr = data->state.buffer;
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--;
if(cl <= 0) {
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;
/* chunked-encoded body, so we need to do the chunked dance
properly to know when the end of the body is reached */
CHUNKcode r;
ssize_t tookcareof = 0;
nread += gotbytes;
/* now parse the chunked piece of data so that we can
properly tell when the stream ends */
r = Curl_httpchunk_read(conn, ptr, 1, &tookcareof);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
keepon = FALSE;
/* we did the full CONNECT treatment, go COMPLETE */
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
}
}
continue;
}
if(keepon > TRUE) {
/* This means we are currently ignoring a response-body */
perline++; /* amount of bytes in this line so far */
nread = 0; /* make next read start over in the read buffer */
ptr=data->state.buffer;
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;
if(cl<=0) {
keepon = FALSE;
break;
}
/* 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);
/* Curl_convert_from_network calls failf if unsuccessful */
if(result)
return result;
/* output debug if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
line_start, (size_t)perline, conn);
/* send the header to the callback */
writetype = CLIENTWRITE_HEADER;
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
result = Curl_client_write(conn, writetype, line_start, perline);
data->info.header_size += (long)perline;
data->req.headerbytecount += (long)perline;
if(result)
return result;
/* Newlines are CRLF, so the CR is ignored as the line isn't
really terminated until the LF comes. Treat a following CR
as end-of-headers as well.*/
if(('\r' == line_start[0]) ||
('\n' == line_start[0])) {
/* end of response-headers from the proxy */
nread = 0; /* make next read start over in the read
buffer */
ptr = data->state.buffer;
if((407 == k->httpcode) && !data->state.authproblem) {
/* If we get a 407 response code with content length
when we have no auth problem, we must ignore the
whole response-body */
keepon = 2;
if(cl) {
infof(data, "Ignore %" CURL_FORMAT_CURL_OFF_T
" bytes of response-body\n", cl);
}
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;
if(line_start[1] == '\n') {
/* this can only be a LF if the letter at index 0
was a CR */
line_start++;
}
else {
/* chunked-encoded body, so we need to do the chunked dance
properly to know when the end of the body is reached */
CHUNKcode r;
ssize_t tookcareof=0;
/* 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);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
keepon = FALSE;
/* 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);
/* 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, 1, &gotbytes);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
keepon = FALSE;
/* we did the full CONNECT treatment, go to
COMPLETE */
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
}
}
else
for(i = 0; i < gotbytes; ptr++, i++) {
perline++; /* amount of bytes in this line so far */
if(*ptr == 0x0a) {
char letter;
int writetype;
/* convert from the network encoding */
result = Curl_convert_from_network(data, line_start,
perline);
/* Curl_convert_from_network calls failf if unsuccessful */
if(result)
return result;
/* output debug if that is requested */
if(data->set.verbose)
Curl_debug(data, CURLINFO_HEADER_IN,
line_start, (size_t)perline, conn);
/* send the header to the callback */
writetype = CLIENTWRITE_HEADER;
if(data->set.include_header)
writetype |= CLIENTWRITE_BODY;
result = Curl_client_write(conn, writetype, line_start,
perline);
data->info.header_size += (long)perline;
data->req.headerbytecount += (long)perline;
if(result)
return result;
/* Newlines are CRLF, so the CR is ignored as the line isn't
really terminated until the LF comes. Treat a following CR
as end-of-headers as well.*/
if(('\r' == line_start[0]) ||
('\n' == line_start[0])) {
/* end of response-headers from the proxy */
nread = 0; /* make next read start over in the read
buffer */
ptr=data->state.buffer;
if((407 == k->httpcode) && !data->state.authproblem) {
/* If we get a 407 response code with content length
when we have no auth problem, we must ignore the
whole response-body */
keepon = 2;
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;
/* 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);
if(r == CHUNKE_STOP) {
/* we're done reading chunks! */
infof(data, "chunk reading DONE\n");
keepon = FALSE;
/* we did the full CONNECT treatment, go to
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
can't keep the connection alive since the close is
the end signal so we bail out at once instead */
keepon=FALSE;
}
}
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() */
}
/* 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)) ||
(checkprefix("Proxy-authenticate:", line_start) &&
(407 == k->httpcode))) {
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
char *auth = Curl_copy_header_value(line_start);
if(!auth)
return CURLE_OUT_OF_MEMORY;
result = Curl_http_input_auth(conn, proxy, auth);
free(auth);
if(result)
return result;
}
else if(checkprefix("Content-Length:", line_start)) {
cl = curlx_strtoofft(line_start +
strlen("Content-Length:"), NULL, 10);
}
else if(Curl_compareheader(line_start,
"Connection:", "close"))
closeConnection = TRUE;
else if(Curl_compareheader(line_start,
"Transfer-Encoding:",
"chunked")) {
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"))
closeConnection = TRUE;
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
&subversion,
&k->httpcode)) {
/* 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 */
}
}
else {
/* without content-length or chunked encoding, we
can't keep the connection alive since the close is
the end signal so we bail out at once instead */
keepon = FALSE;
}
}
break;
} /* switch */
if(Curl_pgrsUpdate(conn))
return CURLE_ABORTED_BY_CALLBACK;
else
keepon = FALSE;
/* we did the full CONNECT treatment, go to COMPLETE */
conn->tunnel_state[sockindex] = TUNNEL_COMPLETE;
continue;
}
line_start[perline] = 0; /* zero terminate the buffer */
if((checkprefix("WWW-Authenticate:", line_start) &&
(401 == k->httpcode)) ||
(checkprefix("Proxy-authenticate:", line_start) &&
(407 == k->httpcode))) {
bool proxy = (k->httpcode == 407) ? TRUE : FALSE;
char *auth = Curl_copy_header_value(line_start);
if(!auth)
return CURLE_OUT_OF_MEMORY;
result = Curl_http_input_auth(conn, proxy, auth);
free(auth);
if(result)
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"))
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"))
closeConnection = TRUE;
else if(2 == sscanf(line_start, "HTTP/1.%d %d",
&subversion,
&k->httpcode)) {
/* store the HTTP code from the proxy */
data->info.httpproxycode = k->httpcode;
}
perline = 0; /* line starts over here */
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;
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;
}
@ -596,7 +634,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
data->state.authproxy.done = TRUE;
infof (data, "Proxy replied OK to CONNECT request\n");
infof(data, "Proxy replied OK to CONNECT request\n");
data->req.ignorebody = FALSE; /* put it (back) to non-ignore state */
conn->bits.rewindaftersend = FALSE; /* make sure this isn't set for the
document request */

View File

@ -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 */

View File

@ -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"
@ -68,7 +68,7 @@ unsigned int Curl_ipv6_scope(const struct sockaddr *sa)
#else
if(sa->sa_family == AF_INET6) {
const struct sockaddr_in6 * sa6 = (const struct sockaddr_in6 *)(void *) sa;
const unsigned char * b = sa6->sin6_addr.s6_addr;
const unsigned char *b = sa6->sin6_addr.s6_addr;
unsigned short w = (unsigned short) ((b[0] << 8) | b[1]);
switch(w & 0xFFC0) {
@ -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;
}
}

View File

@ -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"
@ -108,7 +107,7 @@ static CURLcode imap_perform_authenticate(struct connectdata *conn,
const char *initresp);
static CURLcode imap_continue_authenticate(struct connectdata *conn,
const char *resp);
static void imap_get_message(char *buffer, char** outptr);
static void imap_get_message(char *buffer, char **outptr);
/*
* IMAP protocol handler.
@ -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;
@ -391,10 +391,10 @@ static bool imap_endofresp(struct connectdata *conn, char *line, size_t len,
*
* Gets the authentication message from the response buffer.
*/
static void imap_get_message(char *buffer, char** outptr)
static void imap_get_message(char *buffer, char **outptr)
{
size_t len = 0;
char* message = NULL;
char *message = NULL;
/* Find the start of the message */
for(message = buffer + 2; *message == ' ' || *message == '\t'; message++)
@ -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];

View File

@ -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;

View File

@ -182,12 +182,12 @@ static char *inet_ntop6 (const unsigned char *src, char *dst, size_t size)
*/
char *Curl_inet_ntop(int af, const void *src, char *buf, size_t size)
{
switch (af) {
switch(af) {
case AF_INET:
return inet_ntop4((const unsigned char*)src, buf, size);
return inet_ntop4((const unsigned char *)src, buf, size);
#ifdef ENABLE_IPV6
case AF_INET6:
return inet_ntop6((const unsigned char*)src, buf, size);
return inet_ntop6((const unsigned char *)src, buf, size);
#endif
default:
SET_ERRNO(EAFNOSUPPORT);

View File

@ -65,7 +65,7 @@ static int inet_pton6(const char *src, unsigned char *dst);
int
Curl_inet_pton(int af, const char *src, void *dst)
{
switch (af) {
switch(af) {
case AF_INET:
return (inet_pton4(src, (unsigned char *)dst));
#ifdef ENABLE_IPV6
@ -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;

View File

@ -121,7 +121,7 @@ krb5_encode(void *app_data, const void *from, int length, int level, void **to)
/* NOTE that the cast is safe, neither of the krb5, gnu gss and heimdal
* libraries modify the input buffer in gss_seal()
*/
dec.value = (void*)from;
dec.value = (void *)from;
dec.length = length;
maj = gss_seal(&min, *context,
level == PROT_PRIVATE,
@ -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);

View File

@ -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"
@ -110,9 +109,9 @@ typedef struct {
#undef LDAPURLDesc
#define LDAPURLDesc CURL_LDAPURLDesc
static int _ldap_url_parse (const struct connectdata *conn,
LDAPURLDesc **ludp);
static void _ldap_free_urldesc (LDAPURLDesc *ludp);
static int _ldap_url_parse(const struct connectdata *conn,
LDAPURLDesc **ludp);
static void _ldap_free_urldesc(LDAPURLDesc *ludp);
#undef ldap_free_urldesc
#define ldap_free_urldesc _ldap_free_urldesc
@ -120,11 +119,11 @@ static void _ldap_free_urldesc (LDAPURLDesc *ludp);
#ifdef DEBUG_LDAP
#define LDAP_TRACE(x) do { \
_ldap_trace ("%u: ", __LINE__); \
_ldap_trace("%u: ", __LINE__); \
_ldap_trace x; \
} WHILE_FALSE
static void _ldap_trace (const char *fmt, ...);
static void _ldap_trace(const char *fmt, ...);
#else
#define LDAP_TRACE(x) Curl_nop_stmt
#endif
@ -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;
@ -656,7 +655,7 @@ static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
quit:
if(ldapmsg) {
ldap_msgfree(ldapmsg);
LDAP_TRACE (("Received %d entries\n", num));
LDAP_TRACE(("Received %d entries\n", num));
}
if(rc == LDAP_SIZELIMIT_EXCEEDED)
infof(data, "There are more than %d entries\n", num);
@ -683,7 +682,7 @@ quit:
}
#ifdef DEBUG_LDAP
static void _ldap_trace (const char *fmt, ...)
static void _ldap_trace(const char *fmt, ...)
{
static int do_trace = -1;
va_list args;
@ -695,9 +694,9 @@ static void _ldap_trace (const char *fmt, ...)
if(!do_trace)
return;
va_start (args, fmt);
vfprintf (stderr, fmt, args);
va_end (args);
va_start(args, fmt);
vfprintf(stderr, fmt, args);
va_end(args);
}
#endif
@ -706,18 +705,18 @@ static void _ldap_trace (const char *fmt, ...)
/*
* Return scope-value for a scope-string.
*/
static int str2scope (const char *p)
static int str2scope(const char *p)
{
if(strequal(p, "one"))
return LDAP_SCOPE_ONELEVEL;
if(strequal(p, "onetree"))
return LDAP_SCOPE_ONELEVEL;
if(strequal(p, "base"))
return LDAP_SCOPE_BASE;
if(strequal(p, "sub"))
return LDAP_SCOPE_SUBTREE;
if(strequal(p, "subtree"))
return LDAP_SCOPE_SUBTREE;
if(strcasecompare(p, "one"))
return LDAP_SCOPE_ONELEVEL;
if(strcasecompare(p, "onetree"))
return LDAP_SCOPE_ONELEVEL;
if(strcasecompare(p, "base"))
return LDAP_SCOPE_BASE;
if(strcasecompare(p, "sub"))
return LDAP_SCOPE_SUBTREE;
if(strcasecompare(p, "subtree"))
return LDAP_SCOPE_SUBTREE;
return (-1);
}
@ -767,7 +766,7 @@ static bool split_str(char *str, char ***out, size_t *count)
*
* Defined in RFC4516 section 2.
*/
static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
static int _ldap_url_parse2(const struct connectdata *conn, LDAPURLDesc *ludp)
{
int rc = LDAP_SUCCESS;
char *path;
@ -776,9 +775,9 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
size_t i;
if(!conn->data ||
!conn->data->state.path ||
conn->data->state.path[0] != '/' ||
!checkprefix("LDAP", conn->data->change.url))
!conn->data->state.path ||
conn->data->state.path[0] != '/' ||
!checkprefix("LDAP", conn->data->change.url))
return LDAP_INVALID_SYNTAX;
ludp->lud_scope = LDAP_SCOPE_BASE;
@ -798,12 +797,13 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
if(*p) {
char *dn = p;
char *unescaped;
CURLcode result;
LDAP_TRACE (("DN '%s'\n", dn));
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]));
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;
@ -915,7 +917,7 @@ static int _ldap_url_parse2 (const struct connectdata *conn, LDAPURLDesc *ludp)
goto quit;
}
LDAP_TRACE (("scope %d\n", ludp->lud_scope));
LDAP_TRACE(("scope %d\n", ludp->lud_scope));
}
p = q;
@ -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));
LDAP_TRACE(("filter '%s'\n", filter));
/* Unescape the filter */
unescaped = curl_easy_unescape(conn->data, filter, 0, NULL);
if(!unescaped) {
result = Curl_urldecode(conn->data, filter, 0, &unescaped, NULL, FALSE);
if(result) {
rc = LDAP_NO_MEMORY;
goto quit;
@ -971,8 +974,8 @@ quit:
return rc;
}
static int _ldap_url_parse (const struct connectdata *conn,
LDAPURLDesc **ludpp)
static int _ldap_url_parse(const struct connectdata *conn,
LDAPURLDesc **ludpp)
{
LDAPURLDesc *ludp = calloc(1, sizeof(*ludp));
int rc;
@ -981,7 +984,7 @@ static int _ldap_url_parse (const struct connectdata *conn,
if(!ludp)
return LDAP_NO_MEMORY;
rc = _ldap_url_parse2 (conn, ludp);
rc = _ldap_url_parse2(conn, ludp);
if(rc != LDAP_SUCCESS) {
_ldap_free_urldesc(ludp);
ludp = NULL;
@ -990,7 +993,7 @@ static int _ldap_url_parse (const struct connectdata *conn,
return (rc);
}
static void _ldap_free_urldesc (LDAPURLDesc *ludp)
static void _ldap_free_urldesc(LDAPURLDesc *ludp)
{
size_t i;
@ -1006,7 +1009,7 @@ static void _ldap_free_urldesc (LDAPURLDesc *ludp)
free(ludp->lud_attrs);
}
free (ludp);
free(ludp);
}
#endif /* !HAVE_LDAP_URL_PARSE */
#endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */

View File

@ -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 ;

View File

@ -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

View File

@ -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;

View File

@ -45,7 +45,7 @@ static void MD5_Init(MD5_CTX * ctx)
}
static void MD5_Update(MD5_CTX * ctx,
const unsigned char * input,
const unsigned char *input,
unsigned int inputLen)
{
md5_update(ctx, inputLen, input);
@ -71,7 +71,7 @@ static void MD5_Init(MD5_CTX * ctx)
}
static void MD5_Update(MD5_CTX * ctx,
const unsigned char * input,
const unsigned char *input,
unsigned int inputLen)
{
gcry_md_write(*ctx, input, inputLen);
@ -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;

View File

@ -90,7 +90,7 @@ struct memdebug {
union {
curl_off_t o;
double d;
void * p;
void *p;
} mem[1];
/* I'm hoping this is the thing with the strictest alignment
* requirements. That also means we waste some space :-( */
@ -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
}
}

View File

@ -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,39 +295,72 @@ 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!";
my $quiet = $opt_q ? "-s" : "";
my @out = `curl -w %{response_code} $quiet -O $https`;
if(@out && $out[0] == 200) {
$fetched = 1;
} else {
report "Failed downloading HTTPS with curl, trying HTTP with LWP";
# 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} $proto $quiet -o "$txt" "$url"`;
if(@out && $out[0] == 200) {
$fetched = 1;
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)) {
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 {
# 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 {
$fetched = 1;
}
if( !$resp || $resp->code !~ /^(?:200|304)$/ ) {
report "Downloaded $txt";
}
if(!$resp || $resp->code !~ /^(?:200|304)$/) {
report "Unable to download latest data: "
. ($resp? $resp->code . ' - ' . $resp->message : "LWP failed");
exit 1 if -e $crt || ! -r $txt;
}
}
}
@ -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).";

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