Merge pull request #738 from aleksijuvani/curl-update
Update curl to 7.53.1
This commit is contained in:
commit
97856fe923
@ -37,7 +37,7 @@ The following notes apply to libcurl version 7.19.0 and later.
|
||||
also distribute along with it the generated curl/curlbuild.h which has been
|
||||
used to compile it. Otherwise the library will be of no use for the users of
|
||||
the library that you have built. It is _your_ responsibility to provide this
|
||||
file. No one at the cURL project can know how you have built the library.
|
||||
file. No one at the curl project can know how you have built the library.
|
||||
|
||||
* File curl/curlbuild.h includes platform and configuration dependent info,
|
||||
and must not be modified by anyone. Configure script generates it for you.
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -30,6 +30,10 @@
|
||||
* https://cool.haxx.se/mailman/listinfo/curl-library/
|
||||
*/
|
||||
|
||||
#ifdef CURL_NO_OLDIES
|
||||
#define CURL_STRICTER
|
||||
#endif
|
||||
|
||||
#include "curlver.h" /* libcurl version defines */
|
||||
#include "curlbuild.h" /* libcurl build definitions */
|
||||
#include "curlrules.h" /* libcurl rules enforcement */
|
||||
@ -91,7 +95,13 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
|
||||
typedef struct Curl_easy CURL;
|
||||
typedef struct Curl_share CURLSH;
|
||||
#else
|
||||
typedef void CURL;
|
||||
typedef void CURLSH;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* libcurl external API function linkage decorations.
|
||||
@ -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()
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,16 +26,16 @@
|
||||
a script at release-time. This was made its own header file in 7.11.2 */
|
||||
|
||||
/* This is the global package copyright */
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2016 Daniel Stenberg, <daniel@haxx.se>."
|
||||
#define LIBCURL_COPYRIGHT "1996 - 2017 Daniel Stenberg, <daniel@haxx.se>."
|
||||
|
||||
/* This is the version number of the libcurl package from which this header
|
||||
file origins: */
|
||||
#define LIBCURL_VERSION "7.49.1-DEV"
|
||||
#define LIBCURL_VERSION "7.53.1-DEV"
|
||||
|
||||
/* The numeric version number is also available "in parts" by using these
|
||||
defines: */
|
||||
#define LIBCURL_VERSION_MAJOR 7
|
||||
#define LIBCURL_VERSION_MINOR 49
|
||||
#define LIBCURL_VERSION_MINOR 53
|
||||
#define LIBCURL_VERSION_PATCH 1
|
||||
|
||||
/* This is the numeric version of the libcurl version number, meant for easier
|
||||
@ -57,7 +57,7 @@
|
||||
CURL_VERSION_BITS() macro since curl's own configure script greps for it
|
||||
and needs it to contain the full number.
|
||||
*/
|
||||
#define LIBCURL_VERSION_NUM 0x073101
|
||||
#define LIBCURL_VERSION_NUM 0x073501
|
||||
|
||||
/*
|
||||
* This is the date and time when the full source package was created. The
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -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()
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -52,7 +52,11 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#if defined(BUILDING_LIBCURL) || defined(CURL_STRICTER)
|
||||
typedef struct Curl_multi CURLM;
|
||||
#else
|
||||
typedef void CURLM;
|
||||
#endif
|
||||
|
||||
typedef enum {
|
||||
CURLM_CALL_MULTI_PERFORM = -1, /* please call curl_multi_perform() or
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -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);
|
||||
|
@ -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) \
|
||||
|
1
contrib/curl/lib/.gitignore
vendored
1
contrib/curl/lib/.gitignore
vendored
@ -4,7 +4,6 @@
|
||||
*.orig
|
||||
*.rej
|
||||
*.res
|
||||
Makefile.vc*.dist
|
||||
TAGS
|
||||
curl_config.h
|
||||
curl_config.h.in
|
||||
|
@ -87,6 +87,11 @@ endif()
|
||||
|
||||
set_target_properties(${LIB_NAME} PROPERTIES COMPILE_DEFINITIONS BUILDING_LIBCURL)
|
||||
|
||||
if(HIDES_CURL_PRIVATE_SYMBOLS)
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_DEFINITIONS "CURL_HIDDEN_SYMBOLS")
|
||||
set_property(TARGET ${LIB_NAME} APPEND PROPERTY COMPILE_FLAGS ${CURL_CFLAG_SYMBOLS_HIDE})
|
||||
endif()
|
||||
|
||||
# Remove the "lib" prefix since the library is already named "libcurl".
|
||||
set_target_properties(${LIB_NAME} PROPERTIES PREFIX "")
|
||||
set_target_properties(${LIB_NAME} PROPERTIES IMPORT_PREFIX "")
|
||||
|
@ -5,7 +5,7 @@
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
# Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
@ -23,7 +23,7 @@ AUTOMAKE_OPTIONS = foreign nostdinc
|
||||
|
||||
CMAKE_DIST = CMakeLists.txt curl_config.h.cmake
|
||||
|
||||
EXTRA_DIST = Makefile.b32 Makefile.m32 Makefile.vc6 config-win32.h \
|
||||
EXTRA_DIST = Makefile.b32 Makefile.m32 config-win32.h \
|
||||
config-win32ce.h config-riscos.h config-mac.h curl_config.h.in \
|
||||
makefile.dj config-dos.h libcurl.plist libcurl.rc config-amigaos.h \
|
||||
makefile.amiga Makefile.netware nwlib.c nwos.c config-win32ce.h \
|
||||
|
@ -40,31 +40,31 @@ LIB_VTLS_HFILES = vtls/openssl.h vtls/vtls.h vtls/gtls.h \
|
||||
LIB_CFILES = file.c timeval.c base64.c hostip.c progress.c formdata.c \
|
||||
cookie.c http.c sendf.c ftp.c url.c dict.c if2ip.c speedcheck.c \
|
||||
ldap.c version.c getenv.c escape.c mprintf.c telnet.c netrc.c \
|
||||
getinfo.c transfer.c strequal.c easy.c security.c curl_fnmatch.c \
|
||||
getinfo.c transfer.c strcase.c easy.c security.c curl_fnmatch.c \
|
||||
fileinfo.c ftplistparser.c wildcard.c krb5.c memdebug.c http_chunks.c \
|
||||
strtok.c connect.c llist.c hash.c multi.c content_encoding.c share.c \
|
||||
http_digest.c md4.c md5.c http_negotiate.c inet_pton.c strtoofft.c \
|
||||
strerror.c amigaos.c hostasyn.c hostip4.c hostip6.c hostsyn.c \
|
||||
inet_ntop.c parsedate.c select.c tftp.c splay.c strdup.c socks.c \
|
||||
ssh.c rawstr.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
ssh.c curl_addrinfo.c socks_gssapi.c socks_sspi.c \
|
||||
curl_sspi.c slist.c nonblock.c curl_memrchr.c imap.c pop3.c smtp.c \
|
||||
pingpong.c rtsp.c curl_threads.c warnless.c hmac.c curl_rtmp.c \
|
||||
openldap.c curl_gethostname.c gopher.c idn_win32.c \
|
||||
http_proxy.c non-ascii.c asyn-ares.c asyn-thread.c curl_gssapi.c \
|
||||
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c \
|
||||
http_ntlm.c curl_ntlm_wb.c curl_ntlm_core.c curl_sasl.c rand.c \
|
||||
curl_multibyte.c hostcheck.c conncache.c pipeline.c dotdot.c \
|
||||
x509asn1.c http2.c smb.c curl_endian.c curl_des.c system_win32.c
|
||||
|
||||
LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
||||
formdata.h cookie.h http.h sendf.h ftp.h url.h dict.h if2ip.h \
|
||||
speedcheck.h urldata.h curl_ldap.h escape.h telnet.h getinfo.h \
|
||||
strequal.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
strcase.h curl_sec.h memdebug.h http_chunks.h curl_fnmatch.h \
|
||||
wildcard.h fileinfo.h ftplistparser.h strtok.h connect.h llist.h \
|
||||
hash.h content_encoding.h share.h curl_md4.h curl_md5.h http_digest.h \
|
||||
http_negotiate.h inet_pton.h amigaos.h strtoofft.h strerror.h \
|
||||
inet_ntop.h curlx.h curl_memory.h curl_setup.h transfer.h select.h \
|
||||
easyif.h multiif.h parsedate.h tftp.h sockaddr.h splay.h strdup.h \
|
||||
socks.h ssh.h curl_base64.h rawstr.h curl_addrinfo.h curl_sspi.h \
|
||||
socks.h ssh.h curl_base64.h curl_addrinfo.h curl_sspi.h \
|
||||
slist.h nonblock.h curl_memrchr.h imap.h pop3.h smtp.h pingpong.h \
|
||||
rtsp.h curl_threads.h warnless.h curl_hmac.h curl_rtmp.h \
|
||||
curl_gethostname.h gopher.h http_proxy.h non-ascii.h asyn.h \
|
||||
@ -72,7 +72,7 @@ LIB_HFILES = arpa_telnet.h netrc.h file.h timeval.h hostip.h progress.h \
|
||||
curl_sasl.h curl_multibyte.h hostcheck.h conncache.h \
|
||||
curl_setup_once.h multihandle.h setup-vms.h pipeline.h dotdot.h \
|
||||
x509asn1.h http2.h sigpipe.h smb.h curl_endian.h curl_des.h \
|
||||
curl_printf.h system_win32.h
|
||||
curl_printf.h system_win32.h rand.h
|
||||
|
||||
LIB_RCFILES = libcurl.rc
|
||||
|
||||
|
@ -258,6 +258,10 @@ ifdef SSL
|
||||
CFLAGS += -DHAVE_OPENSSL_SRP -DUSE_TLS_SRP
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifdef WINSSL
|
||||
DLL_LIBS += -lcrypt32
|
||||
endif
|
||||
endif
|
||||
ifdef ZLIB
|
||||
INCLUDES += -I"$(ZLIB_PATH)"
|
||||
|
@ -87,7 +87,7 @@ endif
|
||||
TARGET = libcurl
|
||||
VERSION = $(LIBCURL_VERSION)
|
||||
COPYR = Copyright (C) $(LIBCURL_COPYRIGHT_STR)
|
||||
DESCR = cURL libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
|
||||
DESCR = curl libcurl $(LIBCURL_VERSION_STR) ($(LIBARCH)) - https://curl.haxx.se
|
||||
MTSAFE = YES
|
||||
STACK = 64000
|
||||
SCREEN = none
|
||||
|
@ -1,689 +0,0 @@
|
||||
#***************************************************************************
|
||||
# _ _ ____ _
|
||||
# Project ___| | | | _ \| |
|
||||
# / __| | | | |_) | |
|
||||
# | (__| |_| | _ <| |___
|
||||
# \___|\___/|_| \_\_____|
|
||||
#
|
||||
# Copyright (C) 1999 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
#
|
||||
# This software is licensed as described in the file COPYING, which
|
||||
# you should have received as part of this distribution. The terms
|
||||
# are also available at https://curl.haxx.se/docs/copyright.html.
|
||||
#
|
||||
# You may opt to use, copy, modify, merge, publish, distribute and/or sell
|
||||
# copies of the Software, and permit persons to whom the Software is
|
||||
# furnished to do so, under the terms of the COPYING file.
|
||||
#
|
||||
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
# KIND, either express or implied.
|
||||
#
|
||||
#***************************************************************************
|
||||
|
||||
# All files in the Makefile.vc* series are generated automatically from the
|
||||
# one made for MSVC version 6. Alas, if you want to do changes to any of the
|
||||
# files and send back to the project, edit the version six, make your diff and
|
||||
# mail curl-library.
|
||||
|
||||
###########################################################################
|
||||
#
|
||||
# Makefile for building libcurl with MSVC6
|
||||
#
|
||||
# Usage: see usage message below
|
||||
# Should be invoked from \lib directory
|
||||
# Edit the paths and desired library name
|
||||
# SSL path is only required if you intend compiling
|
||||
# with SSL.
|
||||
#
|
||||
# This make file leaves the result either a .lib or .dll file
|
||||
# in the \lib directory. It should be called from the \lib
|
||||
# directory.
|
||||
#
|
||||
# An option would have been to allow the source directory to
|
||||
# be specified, but I saw no requirement.
|
||||
#
|
||||
# Another option would have been to leave the .lib and .dll
|
||||
# files in the "cfg" directory, but then the make file
|
||||
# in \src would need to be changed.
|
||||
#
|
||||
##############################################################
|
||||
|
||||
# ----------------------------------------------
|
||||
# Verify that current subdir is libcurl's 'lib'
|
||||
# ----------------------------------------------
|
||||
|
||||
!IF ! EXIST(.\curl_addrinfo.c)
|
||||
! MESSAGE Can not process this makefile from outside of libcurl's 'lib' subdirectory.
|
||||
! MESSAGE Change to libcurl's 'lib' subdirectory, and try again.
|
||||
! ERROR See previous message.
|
||||
!ENDIF
|
||||
|
||||
# ------------------------------------------------
|
||||
# Makefile.msvc.names provides libcurl file names
|
||||
# ------------------------------------------------
|
||||
|
||||
!INCLUDE ..\winbuild\Makefile.msvc.names
|
||||
|
||||
!IFNDEF OPENSSL_PATH
|
||||
OPENSSL_PATH = ../../openssl-1.0.2a
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF LIBSSH2_PATH
|
||||
LIBSSH2_PATH = ../../libssh2-1.5.0
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF ZLIB_PATH
|
||||
ZLIB_PATH = ../../zlib-1.2.8
|
||||
!ENDIF
|
||||
|
||||
!IFNDEF MACHINE
|
||||
MACHINE = X86
|
||||
!ENDIF
|
||||
|
||||
# USE_WINDOWS_SSPI uses windows libraries to allow NTLM authentication
|
||||
# without an openssl installation and offers the ability to authenticate
|
||||
# using the "current logged in user". Since at least with MSVC6 the sspi.h
|
||||
# header is broken it is either required to install the Windows SDK,
|
||||
# or to fix sspi.h with adding this define at the beginning of sspi.h:
|
||||
# #define FreeCredentialHandle FreeCredentialsHandle
|
||||
#
|
||||
# If, for some reason the Windows SDK is installed but not installed
|
||||
# in the default location, you can specify WINDOWS_SDK_PATH.
|
||||
# It can be downloaded from:
|
||||
# https://msdn.microsoft.com/windows/bb980924.aspx
|
||||
|
||||
# WINDOWS_SSPI = 1
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
!IFNDEF WINDOWS_SDK_PATH
|
||||
WINDOWS_SDK_PATH = "$(PROGRAMFILES)\Microsoft SDK"
|
||||
!ENDIF
|
||||
!ENDIF
|
||||
|
||||
#############################################################
|
||||
## Nothing more to do below this line!
|
||||
|
||||
CCNODBG = cl.exe /O2 /DNDEBUG
|
||||
CCDEBUG = cl.exe /Od /Gm /Zi /D_DEBUG /GZ
|
||||
CFLAGSSSL = /DUSE_OPENSSL /I "$(OPENSSL_PATH)/inc32" /I "$(OPENSSL_PATH)/inc32/openssl"
|
||||
CFLAGSWINSSL = /DUSE_SCHANNEL
|
||||
CFLAGSSSH2 = /DUSE_LIBSSH2 /DCURL_DISABLE_LDAP /DHAVE_LIBSSH2 /DHAVE_LIBSSH2_H /DLIBSSH2_WIN32 /DLIBSSH2_LIBRARY /I "$(LIBSSH2_PATH)/include"
|
||||
CFLAGSZLIB = /DHAVE_ZLIB_H /DHAVE_ZLIB /DHAVE_LIBZ /I "$(ZLIB_PATH)"
|
||||
CFLAGS = /I. /I../include /nologo /W3 /GX /DWIN32 /YX /FD /c /DBUILDING_LIBCURL /D_BIND_TO_CURRENT_VCLIBS_VERSION=1
|
||||
CFLAGSLIB = /DCURL_STATICLIB
|
||||
LNKDLL = link.exe /DLL
|
||||
LNKLIB = link.exe /lib
|
||||
LFLAGS = /nologo /machine:$(MACHINE)
|
||||
SSLLIBS = libeay32.lib ssleay32.lib
|
||||
ZLIBLIBSDLL = zdll.lib
|
||||
ZLIBLIBS = zlib.lib
|
||||
WINLIBS = ws2_32.lib wldap32.lib advapi32.lib
|
||||
CFLAGS = $(CFLAGS)
|
||||
|
||||
CFGSET = FALSE
|
||||
|
||||
!IFDEF WINDOWS_SSPI
|
||||
CFLAGS = $(CFLAGS) /DUSE_WINDOWS_SSPI /I$(WINDOWS_SDK_PATH)\include
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IPV6
|
||||
CFLAGS = $(CFLAGS) /DUSE_IPV6
|
||||
!ENDIF
|
||||
|
||||
!IFDEF USE_IDN
|
||||
CFLAGS = $(CFLAGS) /DUSE_WIN32_IDN /DWANT_IDN_PROTOTYPES
|
||||
!ENDIF
|
||||
|
||||
##############################################################
|
||||
# Runtime library configuration
|
||||
|
||||
RTLIB = /MD
|
||||
RTLIBD = /MDd
|
||||
|
||||
!IF "$(RTLIBCFG)" == "static"
|
||||
RTLIB = /MT
|
||||
RTLIBD = /MTd
|
||||
!ENDIF
|
||||
|
||||
|
||||
######################
|
||||
# release
|
||||
|
||||
!IF "$(CFG)" == "release"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl
|
||||
|
||||
!IF "$(CFG)" == "release-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl
|
||||
|
||||
!IF "$(CFG)" == "release-winssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-winssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-winssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSWINSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# release-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "release-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_REL)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_REL)
|
||||
CC = $(CCNODBG) $(RTLIB) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug
|
||||
|
||||
!IF "$(CFG)" == "debug"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-ssh2-zlib
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-ssh2-zlib"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSH2 = "/LIBPATH:$(LIBSSH2_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32"
|
||||
LNK = $(LNKLIB) $(ZLIBLIBS) $(LFLAGSSSL) $(LFLAGSSSH2) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSSSH2) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = /LIBPATH:$(OPENSSL_PATH)\out32dll
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_STA_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKLIB) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /out:$(DIROBJ)\$(TARGET)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB) $(CFLAGSLIB)
|
||||
CFGSET = TRUE
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LNK = $(LNKDLL) $(WINLIBS) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(LFLAGSSSL) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(ZLIBLIBSDLL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
######################
|
||||
# debug-dll-ssl-dll-zlib-dll
|
||||
|
||||
!IF "$(CFG)" == "debug-dll-ssl-dll-zlib-dll"
|
||||
TARGET = $(LIBCURL_DYN_LIB_DBG)
|
||||
DIROBJ = $(CFG)
|
||||
LFLAGSZLIB = "/LIBPATH:$(ZLIB_PATH)"
|
||||
LFLAGSSSL = "/LIBPATH:$(OPENSSL_PATH)\out32dll"
|
||||
LNK = $(LNKDLL) $(WINLIBS) $(SSLLIBS) $(ZLIBLIBSDLL) $(LFLAGSSSL) $(LFLAGSZLIB) /DEBUG /out:$(DIROBJ)\$(TARGET) /IMPLIB:$(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) /PDB:$(DIROBJ)\$(LIBCURL_DYN_LIB_PDB)
|
||||
CC = $(CCDEBUG) $(RTLIBD) $(CFLAGSSSL) $(CFLAGSZLIB)
|
||||
CFGSET = TRUE
|
||||
RESOURCE = $(DIROBJ)\libcurl.res
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Usage
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE" && "$(CFG)" != ""
|
||||
!MESSAGE Usage: nmake /f makefile.vc6 CFG=<config> <target>
|
||||
!MESSAGE where <config> is one of:
|
||||
!MESSAGE release - release static library
|
||||
!MESSAGE release-ssl - release static library with ssl
|
||||
!MESSAGE release-zlib - release static library with zlib
|
||||
!MESSAGE release-ssl-zlib - release static library with ssl and zlib
|
||||
!MESSAGE release-ssl-ssh2-zlib - release static library with ssl, ssh2 and zlib
|
||||
!MESSAGE release-ssl-dll - release static library with dynamic ssl
|
||||
!MESSAGE release-zlib-dll - release static library with dynamic zlib
|
||||
!MESSAGE release-ssl-dll-zlib-dll - release static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE release-dll - release dynamic library
|
||||
!MESSAGE release-dll-ssl-dll - release dynamic library with dynamic ssl
|
||||
!MESSAGE release-dll-zlib-dll - release dynamic library with dynamic zlib
|
||||
!MESSAGE release-dll-ssl-dll-zlib-dll - release dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug - debug static library
|
||||
!MESSAGE debug-ssl - debug static library with ssl
|
||||
!MESSAGE debug-zlib - debug static library with zlib
|
||||
!MESSAGE debug-ssl-zlib - debug static library with ssl and zlib
|
||||
!MESSAGE debug-ssl-ssh2-zlib - debug static library with ssl, ssh2 and zlib
|
||||
!MESSAGE debug-ssl-dll - debug static library with dynamic ssl
|
||||
!MESSAGE debug-zlib-dll - debug static library with dynamic zlib
|
||||
!MESSAGE debug-ssl-dll-zlib-dll - debug static library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE debug-dll - debug dynamic library
|
||||
!MESSAGE debug-dll-ssl-dll - debug dynamic library with dynamic ssl
|
||||
!MESSAGE debug-dll-zlib-dll - debug dynamic library with dynamic zlib1
|
||||
!MESSAGE debug-dll-ssl-dll-zlib-dll - debug dynamic library with dynamic ssl and dynamic zlib
|
||||
!MESSAGE <target> can be left blank in which case all is assumed
|
||||
!ERROR please choose a valid configuration "$(CFG)"
|
||||
!ENDIF
|
||||
|
||||
#######################
|
||||
# Only the clean target can be used if a config was not provided.
|
||||
#
|
||||
!IF "$(CFGSET)" == "FALSE"
|
||||
clean:
|
||||
@-erase /s *.dll 2> NUL
|
||||
@-erase /s *.exp 2> NUL
|
||||
@-erase /s *.idb 2> NUL
|
||||
@-erase /s *.lib 2> NUL
|
||||
@-erase /s *.obj 2> NUL
|
||||
@-erase /s *.pch 2> NUL
|
||||
@-erase /s *.pdb 2> NUL
|
||||
@-erase /s *.res 2> NUL
|
||||
!ELSE
|
||||
# A config was provided, so the library can be built.
|
||||
#
|
||||
X_OBJS= \
|
||||
$(DIROBJ)\amigaos.obj \
|
||||
$(DIROBJ)\asyn-ares.obj \
|
||||
$(DIROBJ)\asyn-thread.obj \
|
||||
$(DIROBJ)\axtls.obj \
|
||||
$(DIROBJ)\base64.obj \
|
||||
$(DIROBJ)\conncache.obj \
|
||||
$(DIROBJ)\connect.obj \
|
||||
$(DIROBJ)\content_encoding.obj \
|
||||
$(DIROBJ)\cookie.obj \
|
||||
$(DIROBJ)\curl_addrinfo.obj \
|
||||
$(DIROBJ)\curl_des.obj \
|
||||
$(DIROBJ)\curl_endian.obj \
|
||||
$(DIROBJ)\curl_fnmatch.obj \
|
||||
$(DIROBJ)\curl_gethostname.obj \
|
||||
$(DIROBJ)\curl_gssapi.obj \
|
||||
$(DIROBJ)\curl_memrchr.obj \
|
||||
$(DIROBJ)\curl_multibyte.obj \
|
||||
$(DIROBJ)\curl_ntlm_core.obj \
|
||||
$(DIROBJ)\curl_ntlm_wb.obj \
|
||||
$(DIROBJ)\curl_rtmp.obj \
|
||||
$(DIROBJ)\curl_sasl.obj \
|
||||
$(DIROBJ)\curl_sspi.obj \
|
||||
$(DIROBJ)\curl_threads.obj \
|
||||
$(DIROBJ)\cyassl.obj \
|
||||
$(DIROBJ)\darwinssl.obj \
|
||||
$(DIROBJ)\dict.obj \
|
||||
$(DIROBJ)\dotdot.obj \
|
||||
$(DIROBJ)\easy.obj \
|
||||
$(DIROBJ)\escape.obj \
|
||||
$(DIROBJ)\file.obj \
|
||||
$(DIROBJ)\fileinfo.obj \
|
||||
$(DIROBJ)\formdata.obj \
|
||||
$(DIROBJ)\ftp.obj \
|
||||
$(DIROBJ)\ftplistparser.obj \
|
||||
$(DIROBJ)\getenv.obj \
|
||||
$(DIROBJ)\getinfo.obj \
|
||||
$(DIROBJ)\gopher.obj \
|
||||
$(DIROBJ)\gtls.obj \
|
||||
$(DIROBJ)\hash.obj \
|
||||
$(DIROBJ)\hmac.obj \
|
||||
$(DIROBJ)\hostasyn.obj \
|
||||
$(DIROBJ)\hostcheck.obj \
|
||||
$(DIROBJ)\hostip.obj \
|
||||
$(DIROBJ)\hostip4.obj \
|
||||
$(DIROBJ)\hostip6.obj \
|
||||
$(DIROBJ)\hostsyn.obj \
|
||||
$(DIROBJ)\http.obj \
|
||||
$(DIROBJ)\http_chunks.obj \
|
||||
$(DIROBJ)\http_digest.obj \
|
||||
$(DIROBJ)\http_negotiate.obj \
|
||||
$(DIROBJ)\http_ntlm.obj \
|
||||
$(DIROBJ)\http_proxy.obj \
|
||||
$(DIROBJ)\idn_win32.obj \
|
||||
$(DIROBJ)\if2ip.obj \
|
||||
$(DIROBJ)\imap.obj \
|
||||
$(DIROBJ)\inet_ntop.obj \
|
||||
$(DIROBJ)\inet_pton.obj \
|
||||
$(DIROBJ)\krb5.obj \
|
||||
$(DIROBJ)\ldap.obj \
|
||||
$(DIROBJ)\llist.obj \
|
||||
$(DIROBJ)\md4.obj \
|
||||
$(DIROBJ)\md5.obj \
|
||||
$(DIROBJ)\memdebug.obj \
|
||||
$(DIROBJ)\mprintf.obj \
|
||||
$(DIROBJ)\multi.obj \
|
||||
$(DIROBJ)\netrc.obj \
|
||||
$(DIROBJ)\non-ascii.obj \
|
||||
$(DIROBJ)\nonblock.obj \
|
||||
$(DIROBJ)\nss.obj \
|
||||
$(DIROBJ)\openldap.obj \
|
||||
$(DIROBJ)\parsedate.obj \
|
||||
$(DIROBJ)\pingpong.obj \
|
||||
$(DIROBJ)\pipeline.obj \
|
||||
$(DIROBJ)\polarssl.obj \
|
||||
$(DIROBJ)\polarssl_threadlock.obj \
|
||||
$(DIROBJ)\pop3.obj \
|
||||
$(DIROBJ)\progress.obj \
|
||||
$(DIROBJ)\rawstr.obj \
|
||||
$(DIROBJ)\rtsp.obj \
|
||||
$(DIROBJ)\schannel.obj \
|
||||
$(DIROBJ)\security.obj \
|
||||
$(DIROBJ)\select.obj \
|
||||
$(DIROBJ)\sendf.obj \
|
||||
$(DIROBJ)\share.obj \
|
||||
$(DIROBJ)\slist.obj \
|
||||
$(DIROBJ)\smb.obj \
|
||||
$(DIROBJ)\smtp.obj \
|
||||
$(DIROBJ)\socks.obj \
|
||||
$(DIROBJ)\socks_gssapi.obj \
|
||||
$(DIROBJ)\socks_sspi.obj \
|
||||
$(DIROBJ)\speedcheck.obj \
|
||||
$(DIROBJ)\splay.obj \
|
||||
$(DIROBJ)\ssh.obj \
|
||||
$(DIROBJ)\system_win32.obj \
|
||||
$(DIROBJ)\vauth.obj \
|
||||
$(DIROBJ)\cleartext.obj \
|
||||
$(DIROBJ)\cram.obj \
|
||||
$(DIROBJ)\digest.obj \
|
||||
$(DIROBJ)\digest_sspi.obj \
|
||||
$(DIROBJ)\krb5_gssapi.obj \
|
||||
$(DIROBJ)\krb5_sspi.obj \
|
||||
$(DIROBJ)\ntlm.obj \
|
||||
$(DIROBJ)\ntlm_sspi.obj \
|
||||
$(DIROBJ)\oauth2.obj \
|
||||
$(DIROBJ)\spnego_gssapi.obj \
|
||||
$(DIROBJ)\spnego_sspi.obj \
|
||||
$(DIROBJ)\vtls.obj \
|
||||
$(DIROBJ)\openssl.obj \
|
||||
$(DIROBJ)\strdup.obj \
|
||||
$(DIROBJ)\strequal.obj \
|
||||
$(DIROBJ)\strerror.obj \
|
||||
$(DIROBJ)\strtok.obj \
|
||||
$(DIROBJ)\strtoofft.obj \
|
||||
$(DIROBJ)\telnet.obj \
|
||||
$(DIROBJ)\tftp.obj \
|
||||
$(DIROBJ)\timeval.obj \
|
||||
$(DIROBJ)\transfer.obj \
|
||||
$(DIROBJ)\url.obj \
|
||||
$(DIROBJ)\version.obj \
|
||||
$(DIROBJ)\warnless.obj \
|
||||
$(DIROBJ)\wildcard.obj \
|
||||
$(RESOURCE)
|
||||
|
||||
all : $(TARGET)
|
||||
|
||||
$(TARGET): $(X_OBJS)
|
||||
$(LNK) $(LFLAGS) $(X_OBJS)
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_STA_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_DYN_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_REL) . /y
|
||||
-xcopy $(DIROBJ)\$(LIBCURL_IMP_LIB_DBG) . /y
|
||||
-xcopy $(DIROBJ)\*.exp . /y
|
||||
-xcopy $(DIROBJ)\*.pdb . /y
|
||||
|
||||
$(X_OBJS): $(DIROBJ)
|
||||
|
||||
$(DIROBJ):
|
||||
@if not exist "$(DIROBJ)" mkdir $(DIROBJ)
|
||||
|
||||
.SUFFIXES: .c .obj .res
|
||||
|
||||
{.\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vauth\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
{.\vtls\}.c{$(DIROBJ)\}.obj:
|
||||
$(CC) $(CFLAGS) /Fo"$@" $<
|
||||
|
||||
debug-dll\libcurl.res \
|
||||
debug-dll-ssl-dll\libcurl.res \
|
||||
debug-dll-zlib-dll\libcurl.res \
|
||||
debug-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=1 /Fo $@ libcurl.rc
|
||||
|
||||
release-dll\libcurl.res \
|
||||
release-dll-ssl-dll\libcurl.res \
|
||||
release-dll-zlib-dll\libcurl.res \
|
||||
release-dll-ssl-dll-zlib-dll\libcurl.res: libcurl.rc
|
||||
rc /dDEBUGBUILD=0 /Fo $@ libcurl.rc
|
||||
!ENDIF # End of case where a config was provided.
|
@ -57,7 +57,7 @@ bool Curl_amiga_init()
|
||||
}
|
||||
|
||||
if(SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (ULONG) &errno,
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "cURL",
|
||||
SBTM_SETVAL(SBTC_LOGTAGPTR), (ULONG) "curl",
|
||||
TAG_DONE)) {
|
||||
__request("SocketBaseTags ERROR");
|
||||
return FALSE;
|
||||
|
@ -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)
|
||||
|
@ -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;
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
struct addrinfo;
|
||||
struct hostent;
|
||||
struct SessionHandle;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
struct Curl_dns_entry;
|
||||
|
||||
|
@ -23,7 +23,7 @@
|
||||
/* Base64 encoding/decoding */
|
||||
|
||||
#include "curl_setup.h"
|
||||
#include "urldata.h" /* for the SessionHandle definition */
|
||||
#include "urldata.h" /* for the Curl_easy definition */
|
||||
#include "warnless.h"
|
||||
#include "curl_base64.h"
|
||||
#include "non-ascii.h"
|
||||
@ -169,7 +169,7 @@ CURLcode Curl_base64_decode(const char *src,
|
||||
}
|
||||
|
||||
static CURLcode base64_encode(const char *table64,
|
||||
struct SessionHandle *data,
|
||||
struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
@ -190,6 +190,11 @@ static CURLcode base64_encode(const char *table64,
|
||||
if(!insize)
|
||||
insize = strlen(indata);
|
||||
|
||||
#if SIZEOF_SIZE_T == 4
|
||||
if(insize > UINT_MAX/4)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
#endif
|
||||
|
||||
base64data = output = malloc(insize * 4 / 3 + 4);
|
||||
if(!output)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
@ -283,7 +288,7 @@ static CURLcode base64_encode(const char *table64,
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
@ -307,7 +312,7 @@ CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
*
|
||||
* @unittest: 1302
|
||||
*/
|
||||
CURLcode Curl_base64url_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen)
|
||||
{
|
||||
|
@ -55,7 +55,10 @@ my %warnings = (
|
||||
'COPYRIGHT' => 'file missing a copyright statement',
|
||||
'BADCOMMAND' => 'bad !checksrc! instruction',
|
||||
'UNUSEDIGNORE' => 'a warning ignore was not used',
|
||||
'OPENCOMMENT' => 'file ended with a /* comment still "open"'
|
||||
'OPENCOMMENT' => 'file ended with a /* comment still "open"',
|
||||
'ASTERISKSPACE' => 'pointer declared with space after asterisk',
|
||||
'ASTERISKNOSPACE' => 'pointer declared without space before asterisk',
|
||||
'ASSIGNWITHINCONDITION' => 'assignment within conditional expression'
|
||||
);
|
||||
|
||||
sub readwhitelist {
|
||||
@ -241,6 +244,12 @@ sub checksrc {
|
||||
}
|
||||
}
|
||||
|
||||
sub nostrings {
|
||||
my ($str) = @_;
|
||||
$str =~ s/\".*\"//g;
|
||||
return $str;
|
||||
}
|
||||
|
||||
sub scanfile {
|
||||
my ($file) = @_;
|
||||
|
||||
@ -327,17 +336,35 @@ sub scanfile {
|
||||
$line, length($1), $file, $l, "\/\/ comment");
|
||||
}
|
||||
|
||||
# check spaces after for/if/while
|
||||
if($l =~ /^(.*)(for|if|while) \(/) {
|
||||
my $nostr = nostrings($l);
|
||||
# check spaces after for/if/while/function call
|
||||
if($nostr =~ /^(.*)(for|if|while| ([a-zA-Z0-9_]+)) \((.)/) {
|
||||
if($1 =~ / *\#/) {
|
||||
# this is a #if, treat it differently
|
||||
}
|
||||
elsif($3 eq "return") {
|
||||
# return must have a space
|
||||
}
|
||||
elsif($4 eq "*") {
|
||||
# (* beginning makes the space OK!
|
||||
}
|
||||
elsif($1 =~ / *typedef/) {
|
||||
# typedefs can use space-paren
|
||||
}
|
||||
else {
|
||||
checkwarn("SPACEBEFOREPAREN", $line, length($1)+length($2), $file, $l,
|
||||
"$2 with space");
|
||||
}
|
||||
}
|
||||
|
||||
if($nostr =~ /^((.*)(if) *\()(.*)\)/) {
|
||||
my $pos = length($1);
|
||||
if($4 =~ / = /) {
|
||||
checkwarn("ASSIGNWITHINCONDITION",
|
||||
$line, $pos+1, $file, $l,
|
||||
"assignment within conditional expression");
|
||||
}
|
||||
}
|
||||
# check spaces after open parentheses
|
||||
if($l =~ /^(.*[a-z])\( /i) {
|
||||
checkwarn("SPACEAFTERPAREN",
|
||||
@ -421,7 +448,14 @@ sub scanfile {
|
||||
}
|
||||
|
||||
# scan for use of banned functions
|
||||
if($l =~ /^(.*\W)(sprintf|vsprintf|strcat|strncat|_mbscat|_mbsncat|_tcscat|_tcsncat|wcscat|wcsncat|gets)\s*\(/) {
|
||||
if($l =~ /^(.*\W)
|
||||
(gets|
|
||||
strtok|
|
||||
v?sprintf|
|
||||
(str|_mbs|_tcs|_wcs)n?cat|
|
||||
LoadLibrary(Ex)?(A|W)?)
|
||||
\s*\(
|
||||
/x) {
|
||||
checkwarn("BANNEDFUNC",
|
||||
$line, length($1), $file, $ol,
|
||||
"use of $2 is banned");
|
||||
@ -464,6 +498,31 @@ sub scanfile {
|
||||
}
|
||||
}
|
||||
|
||||
# check for 'char * name'
|
||||
if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost) *(\*+)) (\w+)/) && ($4 ne "const")) {
|
||||
checkwarn("ASTERISKNOSPACE",
|
||||
$line, length($1), $file, $ol,
|
||||
"no space after declarative asterisk");
|
||||
}
|
||||
# check for 'char*'
|
||||
if(($l =~ /(^.*(char|int|long|void|curl_slist|CURL|CURLM|CURLMsg|curl_httppost|sockaddr_in|FILE)\*)/)) {
|
||||
checkwarn("ASTERISKNOSPACE",
|
||||
$line, length($1)-1, $file, $ol,
|
||||
"no space before asterisk");
|
||||
}
|
||||
|
||||
# check for 'void func() {', but avoid false positives by requiring
|
||||
# both an open and closed parentheses before the open brace
|
||||
if($l =~ /^((\w).*){\z/) {
|
||||
my $k = $1;
|
||||
$k =~ s/const *//;
|
||||
$k =~ s/static *//;
|
||||
if($k =~ /\(.*\)/) {
|
||||
checkwarn("BRACEPOS",
|
||||
$line, length($l)-1, $file, $ol,
|
||||
"wrongly placed open brace");
|
||||
}
|
||||
}
|
||||
$line++;
|
||||
$prevl = $ol;
|
||||
}
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -98,7 +98,7 @@
|
||||
#define OS "AmigaOS"
|
||||
|
||||
#define PACKAGE "curl"
|
||||
#define PACKAGE_BUGREPORT "curl-bug@haxx.se"
|
||||
#define PACKAGE_BUGREPORT "a suitable mailing list: https://curl.haxx.se/mail/"
|
||||
#define PACKAGE_NAME "curl"
|
||||
#define PACKAGE_STRING "curl -"
|
||||
#define PACKAGE_TARNAME "curl"
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -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
|
||||
|
@ -30,7 +30,6 @@
|
||||
#include "progress.h"
|
||||
#include "multiif.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "conncache.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -45,7 +44,7 @@ static void conn_llist_dtor(void *user, void *element)
|
||||
data->bundle = NULL;
|
||||
}
|
||||
|
||||
static CURLcode bundle_create(struct SessionHandle *data,
|
||||
static CURLcode bundle_create(struct Curl_easy *data,
|
||||
struct connectbundle **cb_ptr)
|
||||
{
|
||||
(void)data;
|
||||
@ -133,14 +132,16 @@ static char *hashkey(struct connectdata *conn)
|
||||
{
|
||||
const char *hostname;
|
||||
|
||||
if(conn->bits.proxy)
|
||||
hostname = conn->proxy.name;
|
||||
if(conn->bits.socksproxy)
|
||||
hostname = conn->socks_proxy.host.name;
|
||||
else if(conn->bits.httpproxy)
|
||||
hostname = conn->http_proxy.host.name;
|
||||
else if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
|
||||
return aprintf("%s:%d", hostname, conn->port);
|
||||
return aprintf("%s:%ld", hostname, conn->port);
|
||||
}
|
||||
|
||||
/* Look up the bundle with all the connections to the same host this
|
||||
@ -199,7 +200,7 @@ CURLcode Curl_conncache_add_conn(struct conncache *connc,
|
||||
CURLcode result;
|
||||
struct connectbundle *bundle;
|
||||
struct connectbundle *new_bundle = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
bundle = Curl_conncache_find_bundle(conn, data->state.conn_cache);
|
||||
if(!bundle) {
|
||||
|
@ -72,6 +72,7 @@
|
||||
#include "warnless.h"
|
||||
#include "conncache.h"
|
||||
#include "multihandle.h"
|
||||
#include "system_win32.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -103,7 +104,7 @@ struct tcp_keepalive {
|
||||
#endif
|
||||
|
||||
static void
|
||||
tcpkeepalive(struct SessionHandle *data,
|
||||
tcpkeepalive(struct Curl_easy *data,
|
||||
curl_socket_t sockfd)
|
||||
{
|
||||
int optval = data->set.tcp_keepalive?1:0;
|
||||
@ -178,12 +179,12 @@ singleipconnect(struct connectdata *conn,
|
||||
*
|
||||
* @unittest: 1303
|
||||
*/
|
||||
long Curl_timeleft(struct SessionHandle *data,
|
||||
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));
|
||||
}
|
||||
|
@ -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 */
|
||||
|
@ -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)
|
||||
|
@ -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) {
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -70,19 +70,19 @@ struct CookieInfo {
|
||||
#define MAX_NAME 1024
|
||||
#define MAX_NAME_TXT "1023"
|
||||
|
||||
struct SessionHandle;
|
||||
struct Curl_easy;
|
||||
/*
|
||||
* Add a cookie to the internal list of cookies. The domain and path arguments
|
||||
* are only used if the header boolean is TRUE.
|
||||
*/
|
||||
|
||||
struct Cookie *Curl_cookie_add(struct SessionHandle *data,
|
||||
struct Cookie *Curl_cookie_add(struct Curl_easy *data,
|
||||
struct CookieInfo *, bool header, char *lineptr,
|
||||
const char *domain, const char *path);
|
||||
|
||||
struct Cookie *Curl_cookie_getlist(struct CookieInfo *, const char *,
|
||||
const char *, bool);
|
||||
void Curl_cookie_freelist(struct Cookie *cookies, bool cookiestoo);
|
||||
void Curl_cookie_freelist(struct Cookie *cookies);
|
||||
void Curl_cookie_clearall(struct CookieInfo *cookies);
|
||||
void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
|
||||
@ -93,12 +93,12 @@ void Curl_cookie_clearsess(struct CookieInfo *cookies);
|
||||
#define Curl_cookie_cleanup(x) Curl_nop_stmt
|
||||
#define Curl_flush_cookies(x,y) Curl_nop_stmt
|
||||
#else
|
||||
void Curl_flush_cookies(struct SessionHandle *data, int cleanup);
|
||||
void Curl_flush_cookies(struct Curl_easy *data, int cleanup);
|
||||
void Curl_cookie_cleanup(struct CookieInfo *);
|
||||
struct CookieInfo *Curl_cookie_init(struct SessionHandle *data,
|
||||
struct CookieInfo *Curl_cookie_init(struct Curl_easy *data,
|
||||
const char *, struct CookieInfo *, bool);
|
||||
struct curl_slist *Curl_cookie_list(struct SessionHandle *data);
|
||||
void Curl_cookie_loadfiles(struct SessionHandle *data);
|
||||
struct curl_slist *Curl_cookie_list(struct Curl_easy *data);
|
||||
void Curl_cookie_loadfiles(struct Curl_easy *data);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_COOKIE_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -47,6 +47,8 @@
|
||||
# define in_addr_t unsigned long
|
||||
#endif
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
#include "curl_addrinfo.h"
|
||||
#include "inet_pton.h"
|
||||
#include "warnless.h"
|
||||
@ -146,7 +148,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
if((size_t)ai->ai_addrlen < ss_size)
|
||||
continue;
|
||||
|
||||
if((ca = malloc(sizeof(Curl_addrinfo))) == NULL) {
|
||||
ca = malloc(sizeof(Curl_addrinfo));
|
||||
if(!ca) {
|
||||
error = EAI_MEMORY;
|
||||
break;
|
||||
}
|
||||
@ -163,7 +166,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
ca->ai_canonname = NULL;
|
||||
ca->ai_next = NULL;
|
||||
|
||||
if((ca->ai_addr = malloc(ss_size)) == NULL) {
|
||||
ca->ai_addr = malloc(ss_size);
|
||||
if(!ca->ai_addr) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca);
|
||||
break;
|
||||
@ -171,7 +175,8 @@ Curl_getaddrinfo_ex(const char *nodename,
|
||||
memcpy(ca->ai_addr, ai->ai_addr, ss_size);
|
||||
|
||||
if(ai->ai_canonname != NULL) {
|
||||
if((ca->ai_canonname = strdup(ai->ai_canonname)) == NULL) {
|
||||
ca->ai_canonname = strdup(ai->ai_canonname);
|
||||
if(!ca->ai_canonname) {
|
||||
error = EAI_MEMORY;
|
||||
free(ca->ai_addr);
|
||||
free(ca);
|
||||
@ -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
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -80,7 +80,7 @@ Curl_ip2addr(int af, const void *inaddr, const char *hostname, int port);
|
||||
Curl_addrinfo *Curl_str2addr(char *dotted, int port);
|
||||
|
||||
#ifdef USE_UNIX_SOCKETS
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path);
|
||||
Curl_addrinfo *Curl_unix2addr(const char *path, bool *longpath, bool abstract);
|
||||
#endif
|
||||
|
||||
#if defined(CURLDEBUG) && defined(HAVE_GETADDRINFO) && \
|
||||
@ -99,4 +99,12 @@ curl_dogetaddrinfo(const char *hostname,
|
||||
int line, const char *source);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_GETADDRINFO
|
||||
#ifdef USE_RESOLVE_ON_IPS
|
||||
void Curl_addrinfo_set_port(Curl_addrinfo *addrinfo, int port);
|
||||
#else
|
||||
#define Curl_addrinfo_set_port(x,y)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_ADDRINFO_H */
|
||||
|
@ -22,10 +22,10 @@
|
||||
*
|
||||
***************************************************************************/
|
||||
|
||||
CURLcode Curl_base64_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
CURLcode Curl_base64url_encode(struct SessionHandle *data,
|
||||
CURLcode Curl_base64url_encode(struct Curl_easy *data,
|
||||
const char *inputbuff, size_t insize,
|
||||
char **outptr, size_t *outlen);
|
||||
|
||||
|
@ -67,7 +67,7 @@
|
||||
#cmakedefine CURL_DISABLE_VERBOSE_STRINGS 1
|
||||
|
||||
/* to make a symbol visible */
|
||||
#cmakedefine CURL_EXTERN_SYMBOL 1
|
||||
#cmakedefine CURL_EXTERN_SYMBOL ${CURL_EXTERN_SYMBOL}
|
||||
/* Ensure using CURL_EXTERN_SYMBOL is possible */
|
||||
#ifndef CURL_EXTERN_SYMBOL
|
||||
#define CURL_EXTERN_SYMBOL
|
||||
@ -518,6 +518,15 @@
|
||||
/* Define to 1 if you have the send function. */
|
||||
#cmakedefine HAVE_SEND 1
|
||||
|
||||
/* Define to 1 if you have the 'fsetxattr' function. */
|
||||
#cmakedefine HAVE_FSETXATTR 1
|
||||
|
||||
/* fsetxattr() takes 5 args */
|
||||
#cmakedefine HAVE_FSETXATTR_5 1
|
||||
|
||||
/* fsetxattr() takes 6 args */
|
||||
#cmakedefine HAVE_FSETXATTR_6 1
|
||||
|
||||
/* Define to 1 if you have the <setjmp.h> header file. */
|
||||
#cmakedefine HAVE_SETJMP_H 1
|
||||
|
||||
@ -906,6 +915,9 @@
|
||||
/* Define if you want to enable POSIX threaded DNS lookup */
|
||||
#cmakedefine USE_THREADS_POSIX 1
|
||||
|
||||
/* Define if you want to enable WIN32 threaded DNS lookup */
|
||||
#cmakedefine USE_THREADS_WIN32 1
|
||||
|
||||
/* Define to disable non-blocking sockets. */
|
||||
#cmakedefine USE_BLOCKING_SOCKETS 1
|
||||
|
||||
@ -915,6 +927,9 @@
|
||||
/* if PolarSSL is enabled */
|
||||
#cmakedefine USE_POLARSSL 1
|
||||
|
||||
/* if mbedTLS is enabled */
|
||||
#cmakedefine USE_MBEDTLS 1
|
||||
|
||||
/* if libSSH2 is in use */
|
||||
#cmakedefine USE_LIBSSH2 1
|
||||
|
||||
@ -930,11 +945,13 @@
|
||||
/* if OpenSSL is in use */
|
||||
#cmakedefine USE_OPENSSL 1
|
||||
|
||||
/* to enable NGHTTP2 */
|
||||
#cmakedefine USE_NGHTTP2 1
|
||||
|
||||
/* if Unix domain sockets are enabled */
|
||||
#cmakedefine USE_UNIX_SOCKETS
|
||||
|
||||
/* Define to 1 if you are building a Windows target without large file
|
||||
support. */
|
||||
/* Define to 1 if you are building a Windows target with large file support. */
|
||||
#cmakedefine USE_WIN32_LARGE_FILES 1
|
||||
|
||||
/* to enable SSPI support */
|
||||
|
@ -34,7 +34,7 @@
|
||||
*
|
||||
* The function is a port of the Java based oddParity() function over at:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
*
|
||||
* Parameters:
|
||||
*
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -37,7 +37,7 @@
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_le(unsigned char *buf)
|
||||
unsigned short Curl_read16_le(const unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0]) |
|
||||
((unsigned short)buf[1] << 8));
|
||||
@ -56,7 +56,7 @@ unsigned short Curl_read16_le(unsigned char *buf)
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned int Curl_read32_le(unsigned char *buf)
|
||||
unsigned int Curl_read32_le(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0]) | ((unsigned int)buf[1] << 8) |
|
||||
((unsigned int)buf[2] << 16) | ((unsigned int)buf[3] << 24);
|
||||
@ -77,7 +77,7 @@ unsigned int Curl_read32_le(unsigned char *buf)
|
||||
* Returns the integer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_le(unsigned char *buf)
|
||||
unsigned long long Curl_read64_le(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned long long)buf[0]) |
|
||||
((unsigned long long)buf[1] << 8) |
|
||||
@ -89,7 +89,7 @@ unsigned long long Curl_read64_le(unsigned char *buf)
|
||||
((unsigned long long)buf[7] << 56);
|
||||
}
|
||||
#else
|
||||
unsigned __int64 Curl_read64_le(unsigned char *buf)
|
||||
unsigned __int64 Curl_read64_le(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned __int64)buf[0]) | ((unsigned __int64)buf[1] << 8) |
|
||||
((unsigned __int64)buf[2] << 16) | ((unsigned __int64)buf[3] << 24) |
|
||||
@ -113,7 +113,7 @@ unsigned __int64 Curl_read64_le(unsigned char *buf)
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned short Curl_read16_be(unsigned char *buf)
|
||||
unsigned short Curl_read16_be(const unsigned char *buf)
|
||||
{
|
||||
return (unsigned short)(((unsigned short)buf[0] << 8) |
|
||||
((unsigned short)buf[1]));
|
||||
@ -132,7 +132,7 @@ unsigned short Curl_read16_be(unsigned char *buf)
|
||||
*
|
||||
* Returns the integer.
|
||||
*/
|
||||
unsigned int Curl_read32_be(unsigned char *buf)
|
||||
unsigned int Curl_read32_be(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned int)buf[0] << 24) | ((unsigned int)buf[1] << 16) |
|
||||
((unsigned int)buf[2] << 8) | ((unsigned int)buf[3]);
|
||||
@ -153,7 +153,7 @@ unsigned int Curl_read32_be(unsigned char *buf)
|
||||
* Returns the integer.
|
||||
*/
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_be(unsigned char *buf)
|
||||
unsigned long long Curl_read64_be(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned long long)buf[0] << 56) |
|
||||
((unsigned long long)buf[1] << 48) |
|
||||
@ -165,7 +165,7 @@ unsigned long long Curl_read64_be(unsigned char *buf)
|
||||
((unsigned long long)buf[7]);
|
||||
}
|
||||
#else
|
||||
unsigned __int64 Curl_read64_be(unsigned char *buf)
|
||||
unsigned __int64 Curl_read64_be(const unsigned char *buf)
|
||||
{
|
||||
return ((unsigned __int64)buf[0] << 56) | ((unsigned __int64)buf[1] << 48) |
|
||||
((unsigned __int64)buf[2] << 40) | ((unsigned __int64)buf[3] << 32) |
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -23,32 +23,32 @@
|
||||
***************************************************************************/
|
||||
|
||||
/* Converts a 16-bit integer from little endian */
|
||||
unsigned short Curl_read16_le(unsigned char *buf);
|
||||
unsigned short Curl_read16_le(const unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer from little endian */
|
||||
unsigned int Curl_read32_le(unsigned char *buf);
|
||||
unsigned int Curl_read32_le(const unsigned char *buf);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer from little endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_le(unsigned char *buf);
|
||||
unsigned long long Curl_read64_le(const unsigned char *buf);
|
||||
#else
|
||||
unsigned __int64 Curl_read64_le(unsigned char *buf);
|
||||
unsigned __int64 Curl_read64_le(const unsigned char *buf);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/* Converts a 16-bit integer from big endian */
|
||||
unsigned short Curl_read16_be(unsigned char *buf);
|
||||
unsigned short Curl_read16_be(const unsigned char *buf);
|
||||
|
||||
/* Converts a 32-bit integer from big endian */
|
||||
unsigned int Curl_read32_be(unsigned char *buf);
|
||||
unsigned int Curl_read32_be(const unsigned char *buf);
|
||||
|
||||
#if (CURL_SIZEOF_CURL_OFF_T > 4)
|
||||
/* Converts a 64-bit integer from big endian */
|
||||
#if defined(HAVE_LONGLONG)
|
||||
unsigned long long Curl_read64_be(unsigned char *buf);
|
||||
unsigned long long Curl_read64_be(const unsigned char *buf);
|
||||
#else
|
||||
unsigned __int64 Curl_read64_be(unsigned char *buf);
|
||||
unsigned __int64 Curl_read64_be(const unsigned char *buf);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2012, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -48,8 +48,8 @@
|
||||
* For libcurl static library release builds no overriding takes place.
|
||||
*/
|
||||
|
||||
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
|
||||
|
||||
int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen)
|
||||
{
|
||||
#ifndef HAVE_GETHOSTNAME
|
||||
|
||||
/* Allow compilation and return failure when unavailable */
|
||||
@ -59,7 +59,7 @@ int Curl_gethostname(char *name, GETHOSTNAME_TYPE_ARG2 namelen) {
|
||||
|
||||
#else
|
||||
int err;
|
||||
char* dot;
|
||||
char *dot;
|
||||
|
||||
#ifdef DEBUGBUILD
|
||||
|
||||
|
@ -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];
|
||||
|
@ -44,7 +44,7 @@ extern gss_OID_desc Curl_krb5_mech_oid;
|
||||
|
||||
/* Common method for using GSS-API */
|
||||
OM_uint32 Curl_gss_init_sec_context(
|
||||
struct SessionHandle *data,
|
||||
struct Curl_easy *data,
|
||||
OM_uint32 *minor_status,
|
||||
gss_ctx_id_t *context,
|
||||
gss_name_t target_name,
|
||||
@ -56,7 +56,7 @@ OM_uint32 Curl_gss_init_sec_context(
|
||||
OM_uint32 *ret_flags);
|
||||
|
||||
/* Helper to log a GSS-API error status */
|
||||
void Curl_gss_log_error(struct SessionHandle *data, const char *prefix,
|
||||
void Curl_gss_log_error(struct Curl_easy *data, const char *prefix,
|
||||
OM_uint32 major, OM_uint32 minor);
|
||||
|
||||
/* Provide some definitions missing in old headers */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2010, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -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
|
||||
|
||||
|
@ -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);
|
||||
|
@ -64,12 +64,12 @@ void Curl_ntlm_core_lm_resp(const unsigned char *keys,
|
||||
const unsigned char *plaintext,
|
||||
unsigned char *results);
|
||||
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_lm_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *lmbuffer /* 21 bytes */);
|
||||
|
||||
#if USE_NTRESPONSES
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct SessionHandle *data,
|
||||
CURLcode Curl_ntlm_core_mk_nt_hash(struct Curl_easy *data,
|
||||
const char *password,
|
||||
unsigned char *ntbuffer /* 21 bytes */);
|
||||
|
||||
|
@ -28,7 +28,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
@ -51,6 +51,7 @@
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "url.h"
|
||||
#include "strerror.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -156,7 +157,8 @@ static CURLcode ntlm_wb_init(struct connectdata *conn, const char *userp)
|
||||
}
|
||||
slash = strpbrk(username, "\\/");
|
||||
if(slash) {
|
||||
if((domain = strdup(username)) == NULL)
|
||||
domain = strdup(username);
|
||||
if(!domain)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
slash = domain + (slash - username);
|
||||
*slash = '\0';
|
||||
@ -293,11 +295,10 @@ static CURLcode ntlm_wb_response(struct connectdata *conn,
|
||||
buf[len_out - 1] = '\0';
|
||||
break;
|
||||
}
|
||||
newbuf = realloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf) {
|
||||
free(buf);
|
||||
newbuf = Curl_saferealloc(buf, len_out + NTLM_BUFSIZE);
|
||||
if(!newbuf)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
buf = newbuf;
|
||||
}
|
||||
|
||||
@ -349,7 +350,7 @@ CURLcode Curl_output_ntlm_wb(struct connectdata *conn,
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
userp = conn->http_proxy.user;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
|
@ -42,8 +42,6 @@
|
||||
#include "curl_sasl.h"
|
||||
#include "warnless.h"
|
||||
#include "strtok.h"
|
||||
#include "strequal.h"
|
||||
#include "rawstr.h"
|
||||
#include "sendf.h"
|
||||
#include "non-ascii.h" /* included for Curl_convert_... prototypes */
|
||||
/* The last 3 #include files should be in this order */
|
||||
@ -159,7 +157,7 @@ CURLcode Curl_sasl_parse_url_auth_option(struct SASL *sasl,
|
||||
sasl->prefmech = SASL_AUTH_NONE;
|
||||
}
|
||||
|
||||
if(strnequal(value, "*", len))
|
||||
if(!strncmp(value, "*", len))
|
||||
sasl->prefmech = SASL_AUTH_DEFAULT;
|
||||
else {
|
||||
mechbit = Curl_sasl_decode_mech(value, len, &mechlen);
|
||||
@ -257,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);
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
struct SessionHandle;
|
||||
struct Curl_easy;
|
||||
struct connectdata;
|
||||
|
||||
/* Authentication mechanism flags */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2014, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -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
|
||||
|
@ -233,6 +233,15 @@
|
||||
# include "setup-vms.h"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Use getaddrinfo to resolve the IPv4 address literal. If the current network
|
||||
* interface doesn’t support IPv4, but supports IPv6, NAT64, and DNS64,
|
||||
* performing this task will result in a synthesized IPv6 address.
|
||||
*/
|
||||
#ifdef __APPLE__
|
||||
#define USE_RESOLVE_ON_IPS 1
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Include header files for windows builds before redefining anything.
|
||||
* Use this preprocessor block only to include or exclude windows.h,
|
||||
@ -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 */
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -34,8 +34,8 @@
|
||||
functions while they still are offered publicly. They will be made library-
|
||||
private one day */
|
||||
|
||||
#include "strequal.h"
|
||||
/* "strequal.h" provides the strequal protos */
|
||||
#include "strcase.h"
|
||||
/* "strcase.h" provides the strcasecompare protos */
|
||||
|
||||
#include "strtoofft.h"
|
||||
/* "strtoofft.h" provides this function: curlx_strtoofft(), returns a
|
||||
@ -67,15 +67,12 @@
|
||||
be removed from a future libcurl official API:
|
||||
curlx_getenv
|
||||
curlx_mprintf (and its variations)
|
||||
curlx_strequal
|
||||
curlx_strnequal
|
||||
curlx_strcasecompare
|
||||
curlx_strncasecompare
|
||||
|
||||
*/
|
||||
|
||||
#define curlx_getenv curl_getenv
|
||||
#define curlx_strequal curl_strequal
|
||||
#define curlx_strnequal curl_strnequal
|
||||
#define curlx_raw_equal Curl_raw_equal
|
||||
#define curlx_mvsnprintf curl_mvsnprintf
|
||||
#define curlx_msnprintf curl_msnprintf
|
||||
#define curlx_maprintf curl_maprintf
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -52,11 +52,10 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#include "escape.h"
|
||||
#include "progress.h"
|
||||
#include "strequal.h"
|
||||
#include "dict.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
@ -91,17 +90,17 @@ const struct Curl_handler Curl_handler_dict = {
|
||||
PROTOPT_NONE | PROTOPT_NOURLQUERY /* flags */
|
||||
};
|
||||
|
||||
static char *unescape_word(struct SessionHandle *data, const char *inputbuff)
|
||||
static char *unescape_word(struct Curl_easy *data, const char *inputbuff)
|
||||
{
|
||||
char *newp;
|
||||
char *dictp;
|
||||
char *ptr;
|
||||
int len;
|
||||
size_t len;
|
||||
char ch;
|
||||
int olen=0;
|
||||
|
||||
newp = curl_easy_unescape(data, inputbuff, 0, &len);
|
||||
if(!newp)
|
||||
CURLcode result = Curl_urldecode(data, inputbuff, 0, &newp, &len, FALSE);
|
||||
if(!newp || result)
|
||||
return NULL;
|
||||
|
||||
dictp = malloc(((size_t)len)*2 + 1); /* add one for terminating zero */
|
||||
@ -133,7 +132,7 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
char *nthdef = NULL; /* This is not part of the protocol, but required
|
||||
by RFC 2229 */
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
char *path = data->state.path;
|
||||
@ -145,9 +144,9 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
/* AUTH is missing */
|
||||
}
|
||||
|
||||
if(Curl_raw_nequal(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
|
||||
Curl_raw_nequal(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
|
||||
Curl_raw_nequal(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
|
||||
if(strncasecompare(path, DICT_MATCH, sizeof(DICT_MATCH)-1) ||
|
||||
strncasecompare(path, DICT_MATCH2, sizeof(DICT_MATCH2)-1) ||
|
||||
strncasecompare(path, DICT_MATCH3, sizeof(DICT_MATCH3)-1)) {
|
||||
|
||||
word = strchr(path, ':');
|
||||
if(word) {
|
||||
@ -203,9 +202,9 @@ static CURLcode dict_do(struct connectdata *conn, bool *done)
|
||||
Curl_setup_transfer(conn, FIRSTSOCKET, -1, FALSE, bytecount,
|
||||
-1, NULL); /* no upload */
|
||||
}
|
||||
else if(Curl_raw_nequal(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
|
||||
Curl_raw_nequal(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
|
||||
Curl_raw_nequal(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
|
||||
else if(strncasecompare(path, DICT_DEFINE, sizeof(DICT_DEFINE)-1) ||
|
||||
strncasecompare(path, DICT_DEFINE2, sizeof(DICT_DEFINE2)-1) ||
|
||||
strncasecompare(path, DICT_DEFINE3, sizeof(DICT_DEFINE3)-1)) {
|
||||
|
||||
word = strchr(path, ':');
|
||||
if(word) {
|
||||
|
@ -50,7 +50,6 @@
|
||||
#include <sys/param.h>
|
||||
#endif
|
||||
|
||||
#include "strequal.h"
|
||||
#include "urldata.h"
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
@ -144,28 +143,6 @@ static CURLcode win32_init(void)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
/*
|
||||
* Initialise use of IDNA library.
|
||||
* It falls back to ASCII if $CHARSET isn't defined. This doesn't work for
|
||||
* idna_to_ascii_lz().
|
||||
*/
|
||||
static void idna_init (void)
|
||||
{
|
||||
#ifdef WIN32
|
||||
char buf[60];
|
||||
UINT cp = GetACP();
|
||||
|
||||
if(!getenv("CHARSET") && cp > 0) {
|
||||
snprintf(buf, sizeof(buf), "CHARSET=cp%u", cp);
|
||||
putenv(buf);
|
||||
}
|
||||
#else
|
||||
/* to do? */
|
||||
#endif
|
||||
}
|
||||
#endif /* USE_LIBIDN */
|
||||
|
||||
/* true globals -- for curl_global_init() and curl_global_cleanup() */
|
||||
static unsigned int initialized;
|
||||
static long init_flags;
|
||||
@ -217,7 +194,7 @@ curl_calloc_callback Curl_ccalloc;
|
||||
#endif
|
||||
|
||||
/**
|
||||
* curl_global_init() globally initializes cURL given a bitwise set of the
|
||||
* curl_global_init() globally initializes curl given a bitwise set of the
|
||||
* different features of what to initialize.
|
||||
*/
|
||||
static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
@ -262,15 +239,13 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBIDN
|
||||
idna_init();
|
||||
#endif
|
||||
|
||||
if(Curl_resolver_global_init()) {
|
||||
DEBUGF(fprintf(stderr, "Error: resolver_global_init failed\n"));
|
||||
return CURLE_FAILED_INIT;
|
||||
}
|
||||
|
||||
(void)Curl_ipv6works();
|
||||
|
||||
#if defined(USE_LIBSSH2) && defined(HAVE_LIBSSH2_INIT)
|
||||
if(libssh2_init(0)) {
|
||||
DEBUGF(fprintf(stderr, "Error: libssh2_init failed\n"));
|
||||
@ -290,7 +265,7 @@ static CURLcode global_init(long flags, bool memoryfuncs)
|
||||
|
||||
|
||||
/**
|
||||
* curl_global_init() globally initializes cURL given a bitwise set of the
|
||||
* curl_global_init() globally initializes curl given a bitwise set of the
|
||||
* different features of what to initialize.
|
||||
*/
|
||||
CURLcode curl_global_init(long flags)
|
||||
@ -299,7 +274,7 @@ CURLcode curl_global_init(long flags)
|
||||
}
|
||||
|
||||
/*
|
||||
* curl_global_init_mem() globally initializes cURL and also registers the
|
||||
* curl_global_init_mem() globally initializes curl and also registers the
|
||||
* user provided callback routines.
|
||||
*/
|
||||
CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
@ -331,7 +306,7 @@ CURLcode curl_global_init_mem(long flags, curl_malloc_callback m,
|
||||
}
|
||||
|
||||
/**
|
||||
* curl_global_cleanup() globally cleanups cURL, uses the value of
|
||||
* curl_global_cleanup() globally cleanups curl, uses the value of
|
||||
* "init_flags" to determine what needs to be cleaned up and what doesn't.
|
||||
*/
|
||||
void curl_global_cleanup(void)
|
||||
@ -365,10 +340,10 @@ void curl_global_cleanup(void)
|
||||
* curl_easy_init() is the external interface to alloc, setup and init an
|
||||
* easy handle that is returned. If anything goes wrong, NULL is returned.
|
||||
*/
|
||||
CURL *curl_easy_init(void)
|
||||
struct Curl_easy *curl_easy_init(void)
|
||||
{
|
||||
CURLcode result;
|
||||
struct SessionHandle *data;
|
||||
struct Curl_easy *data;
|
||||
|
||||
/* Make sure we inited the global SSL stuff */
|
||||
if(!initialized) {
|
||||
@ -396,13 +371,12 @@ CURL *curl_easy_init(void)
|
||||
*/
|
||||
|
||||
#undef curl_easy_setopt
|
||||
CURLcode curl_easy_setopt(CURL *curl, CURLoption tag, ...)
|
||||
CURLcode curl_easy_setopt(struct Curl_easy *data, CURLoption tag, ...)
|
||||
{
|
||||
va_list arg;
|
||||
struct SessionHandle *data = curl;
|
||||
CURLcode result;
|
||||
|
||||
if(!curl)
|
||||
if(!data)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
||||
va_start(arg, tag);
|
||||
@ -434,7 +408,7 @@ struct events {
|
||||
* updated.
|
||||
*/
|
||||
|
||||
static int events_timer(CURLM *multi, /* multi handle */
|
||||
static int events_timer(struct Curl_multi *multi, /* multi handle */
|
||||
long timeout_ms, /* see above */
|
||||
void *userp) /* private callback pointer */
|
||||
{
|
||||
@ -489,7 +463,7 @@ static short socketcb2poll(int pollmask)
|
||||
* Callback that gets called with information about socket activity to
|
||||
* monitor.
|
||||
*/
|
||||
static int events_socket(CURL *easy, /* easy handle */
|
||||
static int events_socket(struct Curl_easy *easy, /* easy handle */
|
||||
curl_socket_t s, /* socket */
|
||||
int what, /* see above */
|
||||
void *userp, /* private callback
|
||||
@ -567,7 +541,7 @@ static int events_socket(CURL *easy, /* easy handle */
|
||||
*
|
||||
* Do the multi handle setups that only event-based transfers need.
|
||||
*/
|
||||
static void events_setup(CURLM *multi, struct events *ev)
|
||||
static void events_setup(struct Curl_multi *multi, struct events *ev)
|
||||
{
|
||||
/* timer callback */
|
||||
curl_multi_setopt(multi, CURLMOPT_TIMERFUNCTION, events_timer);
|
||||
@ -671,7 +645,7 @@ static CURLcode wait_or_timeout(struct Curl_multi *multi, struct events *ev)
|
||||
*
|
||||
* Runs a transfer in a blocking manner using the events-based API
|
||||
*/
|
||||
static CURLcode easy_events(CURLM *multi)
|
||||
static CURLcode easy_events(struct Curl_multi *multi)
|
||||
{
|
||||
struct events evs= {2, FALSE, 0, NULL, 0};
|
||||
|
||||
@ -685,7 +659,7 @@ static CURLcode easy_events(CURLM *multi)
|
||||
#define easy_events(x) CURLE_NOT_BUILT_IN
|
||||
#endif
|
||||
|
||||
static CURLcode easy_transfer(CURLM *multi)
|
||||
static CURLcode easy_transfer(struct Curl_multi *multi)
|
||||
{
|
||||
bool done = FALSE;
|
||||
CURLMcode mcode = CURLM_OK;
|
||||
@ -765,9 +739,9 @@ static CURLcode easy_transfer(CURLM *multi)
|
||||
* DEBUG: if 'events' is set TRUE, this function will use a replacement engine
|
||||
* instead of curl_multi_perform() and use curl_multi_socket_action().
|
||||
*/
|
||||
static CURLcode easy_perform(struct SessionHandle *data, bool events)
|
||||
static CURLcode easy_perform(struct Curl_easy *data, bool events)
|
||||
{
|
||||
CURLM *multi;
|
||||
struct Curl_multi *multi;
|
||||
CURLMcode mcode;
|
||||
CURLcode result = CURLE_OK;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
@ -827,9 +801,9 @@ static CURLcode easy_perform(struct SessionHandle *data, bool events)
|
||||
* curl_easy_perform() is the external interface that performs a blocking
|
||||
* transfer as previously setup.
|
||||
*/
|
||||
CURLcode curl_easy_perform(CURL *easy)
|
||||
CURLcode curl_easy_perform(struct Curl_easy *data)
|
||||
{
|
||||
return easy_perform(easy, FALSE);
|
||||
return easy_perform(data, FALSE);
|
||||
}
|
||||
|
||||
#ifdef CURLDEBUG
|
||||
@ -837,9 +811,9 @@ CURLcode curl_easy_perform(CURL *easy)
|
||||
* curl_easy_perform_ev() is the external interface that performs a blocking
|
||||
* transfer using the event-based API internally.
|
||||
*/
|
||||
CURLcode curl_easy_perform_ev(CURL *easy)
|
||||
CURLcode curl_easy_perform_ev(struct Curl_easy *data)
|
||||
{
|
||||
return easy_perform(easy, TRUE);
|
||||
return easy_perform(data, TRUE);
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -848,9 +822,8 @@ CURLcode curl_easy_perform_ev(CURL *easy)
|
||||
* curl_easy_cleanup() is the external interface to cleaning/freeing the given
|
||||
* easy handle.
|
||||
*/
|
||||
void curl_easy_cleanup(CURL *curl)
|
||||
void curl_easy_cleanup(struct Curl_easy *data)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
SIGPIPE_VARIABLE(pipe_st);
|
||||
|
||||
if(!data)
|
||||
@ -866,12 +839,11 @@ void curl_easy_cleanup(CURL *curl)
|
||||
* information from a performed transfer and similar.
|
||||
*/
|
||||
#undef curl_easy_getinfo
|
||||
CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
CURLcode curl_easy_getinfo(struct Curl_easy *data, CURLINFO info, ...)
|
||||
{
|
||||
va_list arg;
|
||||
void *paramp;
|
||||
CURLcode result;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
va_start(arg, info);
|
||||
paramp = va_arg(arg, void *);
|
||||
@ -887,11 +859,9 @@ CURLcode curl_easy_getinfo(CURL *curl, CURLINFO info, ...)
|
||||
* given input easy handle. The returned handle will be a new working handle
|
||||
* with all options set exactly as the input source handle.
|
||||
*/
|
||||
CURL *curl_easy_duphandle(CURL *incurl)
|
||||
struct Curl_easy *curl_easy_duphandle(struct Curl_easy *data)
|
||||
{
|
||||
struct SessionHandle *data=(struct SessionHandle *)incurl;
|
||||
|
||||
struct SessionHandle *outcurl = calloc(1, sizeof(struct SessionHandle));
|
||||
struct Curl_easy *outcurl = calloc(1, sizeof(struct Curl_easy));
|
||||
if(NULL == outcurl)
|
||||
goto fail;
|
||||
|
||||
@ -900,6 +870,11 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
* get setup on-demand in the code, as that would probably decrease
|
||||
* the likeliness of us forgetting to init a buffer here in the future.
|
||||
*/
|
||||
outcurl->set.buffer_size = data->set.buffer_size;
|
||||
outcurl->state.buffer = malloc(CURL_BUFSIZE(outcurl->set.buffer_size) + 1);
|
||||
if(!outcurl->state.buffer)
|
||||
goto fail;
|
||||
|
||||
outcurl->state.headerbuff = malloc(HEADERSIZE);
|
||||
if(!outcurl->state.headerbuff)
|
||||
goto fail;
|
||||
@ -957,6 +932,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
|
||||
Curl_convert_setup(outcurl);
|
||||
|
||||
Curl_initinfo(outcurl);
|
||||
|
||||
outcurl->magic = CURLEASY_MAGIC_NUMBER;
|
||||
|
||||
/* we reach this point and thus we are OK */
|
||||
@ -968,6 +945,7 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
if(outcurl) {
|
||||
curl_slist_free_all(outcurl->change.cookielist);
|
||||
outcurl->change.cookielist = NULL;
|
||||
Curl_safefree(outcurl->state.buffer);
|
||||
Curl_safefree(outcurl->state.headerbuff);
|
||||
Curl_safefree(outcurl->change.url);
|
||||
Curl_safefree(outcurl->change.referer);
|
||||
@ -982,10 +960,8 @@ CURL *curl_easy_duphandle(CURL *incurl)
|
||||
* curl_easy_reset() is an external interface that allows an app to re-
|
||||
* initialize a session handle to the default values.
|
||||
*/
|
||||
void curl_easy_reset(CURL *curl)
|
||||
void curl_easy_reset(struct Curl_easy *data)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
Curl_safefree(data->state.pathbuffer);
|
||||
|
||||
data->state.path = NULL;
|
||||
@ -1000,6 +976,9 @@ void curl_easy_reset(CURL *curl)
|
||||
/* zero out Progress data: */
|
||||
memset(&data->progress, 0, sizeof(struct Progress));
|
||||
|
||||
/* zero out PureInfo data: */
|
||||
Curl_initinfo(data);
|
||||
|
||||
data->progress.flags |= PGRS_HIDE;
|
||||
data->state.current_speed = -1; /* init to negative == impossible */
|
||||
}
|
||||
@ -1014,9 +993,8 @@ void curl_easy_reset(CURL *curl)
|
||||
*
|
||||
* Action is a bitmask consisting of CURLPAUSE_* bits in curl/curl.h
|
||||
*/
|
||||
CURLcode curl_easy_pause(CURL *curl, int action)
|
||||
CURLcode curl_easy_pause(struct Curl_easy *data, int action)
|
||||
{
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
struct SingleRequest *k = &data->req;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
@ -1050,13 +1028,13 @@ CURLcode curl_easy_pause(CURL *curl, int action)
|
||||
if(!result &&
|
||||
((newstate&(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) !=
|
||||
(KEEP_RECV_PAUSE|KEEP_SEND_PAUSE)) )
|
||||
Curl_expire(data, 1); /* get this handle going again */
|
||||
Curl_expire(data, 0); /* get this handle going again */
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
static CURLcode easy_connection(struct SessionHandle *data,
|
||||
static CURLcode easy_connection(struct Curl_easy *data,
|
||||
curl_socket_t *sfd,
|
||||
struct connectdata **connp)
|
||||
{
|
||||
@ -1084,13 +1062,13 @@ static CURLcode easy_connection(struct SessionHandle *data,
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
* Returns CURLE_OK on success, error code on error.
|
||||
*/
|
||||
CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
|
||||
CURLcode curl_easy_recv(struct Curl_easy *data, void *buffer, size_t buflen,
|
||||
size_t *n)
|
||||
{
|
||||
curl_socket_t sfd;
|
||||
CURLcode result;
|
||||
ssize_t n1;
|
||||
struct connectdata *c;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
result = easy_connection(data, &sfd, &c);
|
||||
if(result)
|
||||
@ -1111,14 +1089,13 @@ CURLcode curl_easy_recv(CURL *curl, void *buffer, size_t buflen, size_t *n)
|
||||
* Sends data over the connected socket. Use after successful
|
||||
* curl_easy_perform() with CURLOPT_CONNECT_ONLY option.
|
||||
*/
|
||||
CURLcode curl_easy_send(CURL *curl, const void *buffer, size_t buflen,
|
||||
size_t *n)
|
||||
CURLcode curl_easy_send(struct Curl_easy *data, const void *buffer,
|
||||
size_t buflen, size_t *n)
|
||||
{
|
||||
curl_socket_t sfd;
|
||||
CURLcode result;
|
||||
ssize_t n1;
|
||||
struct connectdata *c = NULL;
|
||||
struct SessionHandle *data = (struct SessionHandle *)curl;
|
||||
|
||||
result = easy_connection(data, &sfd, &c);
|
||||
if(result)
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2013, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -26,7 +26,7 @@
|
||||
* Prototypes for library-wide functions provided by easy.c
|
||||
*/
|
||||
#ifdef CURLDEBUG
|
||||
CURL_EXTERN CURLcode curl_easy_perform_ev(CURL *easy);
|
||||
CURL_EXTERN CURLcode curl_easy_perform_ev(struct Curl_easy *easy);
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_EASYIF_H */
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "warnless.h"
|
||||
#include "non-ascii.h"
|
||||
#include "escape.h"
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -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;
|
||||
}
|
||||
|
||||
|
@ -24,7 +24,7 @@
|
||||
/* Escape and unescape URL encoding in strings. The functions return a new
|
||||
* allocated string or NULL if an error occurred. */
|
||||
|
||||
CURLcode Curl_urldecode(struct SessionHandle *data,
|
||||
CURLcode Curl_urldecode(struct Curl_easy *data,
|
||||
const char *string, size_t length,
|
||||
char **ostring, size_t *olen,
|
||||
bool reject_crlf);
|
||||
|
@ -135,7 +135,7 @@ static CURLcode file_range(struct connectdata *conn)
|
||||
curl_off_t totalsize=-1;
|
||||
char *ptr;
|
||||
char *ptr2;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(data->state.use_range && data->state.range) {
|
||||
from=curlx_strtoofft(data->state.range, &ptr, 0);
|
||||
@ -185,19 +185,20 @@ static CURLcode file_range(struct connectdata *conn)
|
||||
*/
|
||||
static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char *real_path;
|
||||
struct FILEPROTO *file = data->req.protop;
|
||||
int fd;
|
||||
#ifdef DOS_FILESYSTEM
|
||||
int i;
|
||||
size_t i;
|
||||
char *actual_path;
|
||||
#endif
|
||||
int real_path_len;
|
||||
size_t real_path_len;
|
||||
|
||||
real_path = curl_easy_unescape(data, data->state.path, 0, &real_path_len);
|
||||
if(!real_path)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
CURLcode result = Curl_urldecode(data, data->state.path, 0, &real_path,
|
||||
&real_path_len, FALSE);
|
||||
if(result)
|
||||
return result;
|
||||
|
||||
#ifdef DOS_FILESYSTEM
|
||||
/* If the first character is a slash, and there's
|
||||
@ -227,15 +228,19 @@ static CURLcode file_connect(struct connectdata *conn, bool *done)
|
||||
for(i=0; i < real_path_len; ++i)
|
||||
if(actual_path[i] == '/')
|
||||
actual_path[i] = '\\';
|
||||
else if(!actual_path[i]) /* binary zero */
|
||||
else if(!actual_path[i]) { /* binary zero */
|
||||
Curl_safefree(real_path);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
fd = open_readonly(actual_path, O_RDONLY|O_BINARY);
|
||||
file->path = actual_path;
|
||||
#else
|
||||
if(memchr(real_path, 0, real_path_len))
|
||||
if(memchr(real_path, 0, real_path_len)) {
|
||||
/* binary zeroes indicate foul play */
|
||||
Curl_safefree(real_path);
|
||||
return CURLE_URL_MALFORMAT;
|
||||
}
|
||||
|
||||
fd = open_readonly(real_path, O_RDONLY);
|
||||
file->path = real_path;
|
||||
@ -301,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)
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
@ -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;
|
||||
|
@ -30,7 +30,8 @@
|
||||
static
|
||||
char *GetEnv(const char *variable)
|
||||
{
|
||||
#ifdef _WIN32_WCE
|
||||
#if defined(_WIN32_WCE) || defined(CURL_WINDOWS_APP)
|
||||
(void)variable;
|
||||
return NULL;
|
||||
#else
|
||||
#ifdef WIN32
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -36,10 +36,13 @@
|
||||
#include "memdebug.h"
|
||||
|
||||
/*
|
||||
* This is supposed to be called in the beginning of a perform() session
|
||||
* and should reset all session-info variables
|
||||
* Initialize statistical and informational data.
|
||||
*
|
||||
* This function is called in curl_easy_reset, curl_easy_duphandle and at the
|
||||
* beginning of a perform session. It must reset the session-info variables,
|
||||
* in particular all variables in struct PureInfo.
|
||||
*/
|
||||
CURLcode Curl_initinfo(struct SessionHandle *data)
|
||||
CURLcode Curl_initinfo(struct Curl_easy *data)
|
||||
{
|
||||
struct Progress *pro = &data->progress;
|
||||
struct PureInfo *info = &data->info;
|
||||
@ -58,23 +61,35 @@ CURLcode Curl_initinfo(struct SessionHandle *data)
|
||||
info->filetime = -1; /* -1 is an illegal time and thus means unknown */
|
||||
info->timecond = FALSE;
|
||||
|
||||
info->header_size = 0;
|
||||
info->request_size = 0;
|
||||
info->proxyauthavail = 0;
|
||||
info->httpauthavail = 0;
|
||||
info->numconnects = 0;
|
||||
|
||||
free(info->contenttype);
|
||||
info->contenttype = NULL;
|
||||
|
||||
info->header_size = 0;
|
||||
info->request_size = 0;
|
||||
info->numconnects = 0;
|
||||
free(info->wouldredirect);
|
||||
info->wouldredirect = NULL;
|
||||
|
||||
info->conn_primary_ip[0] = '\0';
|
||||
info->conn_local_ip[0] = '\0';
|
||||
info->conn_primary_port = 0;
|
||||
info->conn_local_port = 0;
|
||||
|
||||
info->conn_scheme = 0;
|
||||
info->conn_protocol = 0;
|
||||
|
||||
#ifdef USE_SSL
|
||||
Curl_ssl_free_certinfo(data);
|
||||
#endif
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
|
||||
char **param_charp)
|
||||
static CURLcode getinfo_char(struct Curl_easy *data, CURLINFO info,
|
||||
const char **param_charp)
|
||||
{
|
||||
switch(info) {
|
||||
case CURLINFO_EFFECTIVE_URL:
|
||||
@ -111,6 +126,9 @@ static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
|
||||
case CURLINFO_RTSP_SESSION_ID:
|
||||
*param_charp = data->set.str[STRING_RTSP_SESSION_ID];
|
||||
break;
|
||||
case CURLINFO_SCHEME:
|
||||
*param_charp = data->info.conn_scheme;
|
||||
break;
|
||||
|
||||
default:
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
@ -119,7 +137,7 @@ static CURLcode getinfo_char(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_long(struct Curl_easy *data, CURLINFO info,
|
||||
long *param_longp)
|
||||
{
|
||||
curl_socket_t sockfd;
|
||||
@ -148,6 +166,9 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
case CURLINFO_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.ssl.certverifyresult;
|
||||
break;
|
||||
case CURLINFO_PROXY_SSL_VERIFYRESULT:
|
||||
*param_longp = data->set.proxy_ssl.certverifyresult;
|
||||
break;
|
||||
case CURLINFO_REDIRECT_COUNT:
|
||||
*param_longp = data->set.followlocation;
|
||||
break;
|
||||
@ -198,6 +219,25 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
case CURLINFO_RTSP_CSEQ_RECV:
|
||||
*param_longp = data->state.rtsp_CSeq_recv;
|
||||
break;
|
||||
case CURLINFO_HTTP_VERSION:
|
||||
switch(data->info.httpversion) {
|
||||
case 10:
|
||||
*param_longp = CURL_HTTP_VERSION_1_0;
|
||||
break;
|
||||
case 11:
|
||||
*param_longp = CURL_HTTP_VERSION_1_1;
|
||||
break;
|
||||
case 20:
|
||||
*param_longp = CURL_HTTP_VERSION_2_0;
|
||||
break;
|
||||
default:
|
||||
*param_longp = CURL_HTTP_VERSION_NONE;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CURLINFO_PROTOCOL:
|
||||
*param_longp = data->info.conn_protocol;
|
||||
break;
|
||||
|
||||
default:
|
||||
return CURLE_UNKNOWN_OPTION;
|
||||
@ -206,7 +246,7 @@ static CURLcode getinfo_long(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_double(struct Curl_easy *data, CURLINFO info,
|
||||
double *param_doublep)
|
||||
{
|
||||
switch(info) {
|
||||
@ -259,7 +299,7 @@ static CURLcode getinfo_double(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_slist(struct Curl_easy *data, CURLINFO info,
|
||||
struct curl_slist **param_slistp)
|
||||
{
|
||||
union {
|
||||
@ -335,7 +375,7 @@ static CURLcode getinfo_slist(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode getinfo_socket(struct SessionHandle *data, CURLINFO info,
|
||||
static CURLcode getinfo_socket(struct Curl_easy *data, CURLINFO info,
|
||||
curl_socket_t *param_socketp)
|
||||
{
|
||||
switch(info) {
|
||||
@ -349,12 +389,12 @@ static CURLcode getinfo_socket(struct SessionHandle *data, CURLINFO info,
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...)
|
||||
{
|
||||
va_list arg;
|
||||
long *param_longp = NULL;
|
||||
double *param_doublep = NULL;
|
||||
char **param_charp = NULL;
|
||||
const char **param_charp = NULL;
|
||||
struct curl_slist **param_slistp = NULL;
|
||||
curl_socket_t *param_socketp = NULL;
|
||||
int type;
|
||||
@ -368,7 +408,7 @@ CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...)
|
||||
type = CURLINFO_TYPEMASK & (int)info;
|
||||
switch(type) {
|
||||
case CURLINFO_STRING:
|
||||
param_charp = va_arg(arg, char **);
|
||||
param_charp = va_arg(arg, const char **);
|
||||
if(param_charp)
|
||||
result = getinfo_char(data, info, param_charp);
|
||||
break;
|
||||
|
@ -21,7 +21,7 @@
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
***************************************************************************/
|
||||
CURLcode Curl_getinfo(struct SessionHandle *data, CURLINFO info, ...);
|
||||
CURLcode Curl_initinfo(struct SessionHandle *data);
|
||||
CURLcode Curl_getinfo(struct Curl_easy *data, CURLINFO info, ...);
|
||||
CURLcode Curl_initinfo(struct Curl_easy *data);
|
||||
|
||||
#endif /* HEADER_CURL_GETINFO_H */
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -28,13 +28,11 @@
|
||||
#include <curl/curl.h>
|
||||
#include "transfer.h"
|
||||
#include "sendf.h"
|
||||
|
||||
#include "progress.h"
|
||||
#include "strequal.h"
|
||||
#include "gopher.h"
|
||||
#include "rawstr.h"
|
||||
#include "select.h"
|
||||
#include "url.h"
|
||||
#include "escape.h"
|
||||
#include "warnless.h"
|
||||
#include "curl_memory.h"
|
||||
/* The last #include file should be: */
|
||||
@ -75,7 +73,7 @@ const struct Curl_handler Curl_handler_gopher = {
|
||||
static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
curl_socket_t sockfd = conn->sock[FIRSTSOCKET];
|
||||
|
||||
curl_off_t *bytecount = &data->req.bytecount;
|
||||
@ -83,7 +81,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
char *sel;
|
||||
char *sel_org = NULL;
|
||||
ssize_t amount, k;
|
||||
int len;
|
||||
size_t len;
|
||||
|
||||
*done = TRUE; /* unconditionally */
|
||||
|
||||
@ -107,7 +105,7 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
newp[i] = '\x09';
|
||||
|
||||
/* ... and finally unescape */
|
||||
sel = curl_easy_unescape(data, newp, 0, &len);
|
||||
result = Curl_urldecode(data, newp, 0, &sel, &len, FALSE);
|
||||
if(!sel)
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
sel_org = sel;
|
||||
@ -121,20 +119,17 @@ static CURLcode gopher_do(struct connectdata *conn, bool *done)
|
||||
result = Curl_write(conn, sockfd, sel, k, &amount);
|
||||
if(!result) { /* Which may not have written it all! */
|
||||
result = Curl_client_write(conn, CLIENTWRITE_HEADER, sel, amount);
|
||||
if(result) {
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
if(result)
|
||||
break;
|
||||
|
||||
k -= amount;
|
||||
sel += amount;
|
||||
if(k < 1)
|
||||
break; /* but it did write it all */
|
||||
}
|
||||
else {
|
||||
failf(data, "Failed sending Gopher request");
|
||||
free(sel_org);
|
||||
return result;
|
||||
}
|
||||
else
|
||||
break;
|
||||
|
||||
/* Don't busyloop. The entire loop thing is a work-around as it causes a
|
||||
BLOCKING behavior which is a NO-NO. This function should rather be
|
||||
split up in a do and a doing piece where the pieces that aren't
|
||||
@ -144,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;
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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 *
|
||||
|
@ -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;
|
||||
|
||||
|
@ -77,7 +77,7 @@ CURLcode Curl_addrinfo_callback(struct connectdata *conn,
|
||||
|
||||
if(CURL_ASYNC_SUCCESS == status) {
|
||||
if(ai) {
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
if(data->share)
|
||||
Curl_share_lock(data, CURL_LOCK_DATA_DNS, CURL_LOCK_ACCESS_SINGLE);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -22,7 +22,10 @@
|
||||
|
||||
#include "curl_setup.h"
|
||||
|
||||
#if defined(USE_OPENSSL) || defined(USE_AXTLS) || defined(USE_GSKIT)
|
||||
#if defined(USE_OPENSSL) \
|
||||
|| defined(USE_AXTLS) \
|
||||
|| defined(USE_GSKIT) \
|
||||
|| (defined(USE_SCHANNEL) && defined(_WIN32_WCE))
|
||||
/* these backends use functions from this file */
|
||||
|
||||
#ifdef HAVE_NETINET_IN_H
|
||||
@ -30,7 +33,7 @@
|
||||
#endif
|
||||
|
||||
#include "hostcheck.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "inet_pton.h"
|
||||
|
||||
#include "curl_memory.h"
|
||||
@ -77,7 +80,7 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
|
||||
pattern_wildcard = strchr(pattern, '*');
|
||||
if(pattern_wildcard == NULL)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
return strcasecompare(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
/* detect IP address as hostname and fail the match if so */
|
||||
@ -94,16 +97,16 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
pattern_label_end = strchr(pattern, '.');
|
||||
if(pattern_label_end == NULL || strchr(pattern_label_end+1, '.') == NULL ||
|
||||
pattern_wildcard > pattern_label_end ||
|
||||
Curl_raw_nequal(pattern, "xn--", 4)) {
|
||||
strncasecompare(pattern, "xn--", 4)) {
|
||||
wildcard_enabled = 0;
|
||||
}
|
||||
if(!wildcard_enabled)
|
||||
return Curl_raw_equal(pattern, hostname) ?
|
||||
return strcasecompare(pattern, hostname) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
|
||||
hostname_label_end = strchr(hostname, '.');
|
||||
if(hostname_label_end == NULL ||
|
||||
!Curl_raw_equal(pattern_label_end, hostname_label_end))
|
||||
!strcasecompare(pattern_label_end, hostname_label_end))
|
||||
return CURL_HOST_NOMATCH;
|
||||
|
||||
/* The wildcard must match at least one character, so the left-most
|
||||
@ -114,8 +117,8 @@ static int hostmatch(char *hostname, char *pattern)
|
||||
|
||||
prefixlen = pattern_wildcard - pattern;
|
||||
suffixlen = pattern_label_end - (pattern_wildcard+1);
|
||||
return Curl_raw_nequal(pattern, hostname, prefixlen) &&
|
||||
Curl_raw_nequal(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
return strncasecompare(pattern, hostname, prefixlen) &&
|
||||
strncasecompare(pattern_wildcard+1, hostname_label_end - suffixlen,
|
||||
suffixlen) ?
|
||||
CURL_HOST_MATCH : CURL_HOST_NOMATCH;
|
||||
}
|
||||
@ -144,4 +147,4 @@ int Curl_cert_hostcheck(const char *match_pattern, const char *hostname)
|
||||
return res;
|
||||
}
|
||||
|
||||
#endif /* OPENSSL or AXTLS or GSKIT */
|
||||
#endif /* OPENSSL, AXTLS, GSKIT or schannel+wince */
|
||||
|
@ -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];
|
||||
|
@ -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 */
|
||||
|
@ -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 */
|
||||
}
|
||||
|
||||
|
@ -167,10 +167,12 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
int error;
|
||||
char sbuf[12];
|
||||
char *sbufptr = NULL;
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
char addrbuf[128];
|
||||
#endif
|
||||
int pf;
|
||||
#if !defined(CURL_DISABLE_VERBOSE_STRINGS)
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
#endif
|
||||
|
||||
*waitp = 0; /* synchronous response only */
|
||||
@ -196,11 +198,17 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
hints.ai_family = pf;
|
||||
hints.ai_socktype = conn->socktype;
|
||||
|
||||
#ifndef USE_RESOLVE_ON_IPS
|
||||
/*
|
||||
* The AI_NUMERICHOST must not be set to get synthesized IPv6 address from
|
||||
* an IPv4 address on iOS and Mac OS X.
|
||||
*/
|
||||
if((1 == Curl_inet_pton(AF_INET, hostname, addrbuf)) ||
|
||||
(1 == Curl_inet_pton(AF_INET6, hostname, addrbuf))) {
|
||||
/* the given address is numerical only, prevent a reverse lookup */
|
||||
hints.ai_flags = AI_NUMERICHOST;
|
||||
}
|
||||
#endif
|
||||
|
||||
if(port) {
|
||||
snprintf(sbuf, sizeof(sbuf), "%d", port);
|
||||
@ -213,6 +221,10 @@ Curl_addrinfo *Curl_getaddrinfo(struct connectdata *conn,
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(port) {
|
||||
Curl_addrinfo_set_port(res, port);
|
||||
}
|
||||
|
||||
dump_addrinfo(conn, res);
|
||||
|
||||
return res;
|
||||
|
@ -59,7 +59,7 @@
|
||||
/*
|
||||
* Function provided by the resolver backend to set DNS servers to use.
|
||||
*/
|
||||
CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_servers(struct Curl_easy *data,
|
||||
char *servers)
|
||||
{
|
||||
(void)data;
|
||||
@ -72,7 +72,7 @@ CURLcode Curl_set_dns_servers(struct SessionHandle *data,
|
||||
* Function provided by the resolver backend to set
|
||||
* outgoing interface to use for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_interface(struct Curl_easy *data,
|
||||
const char *interf)
|
||||
{
|
||||
(void)data;
|
||||
@ -84,7 +84,7 @@ CURLcode Curl_set_dns_interface(struct SessionHandle *data,
|
||||
* Function provided by the resolver backend to set
|
||||
* local IPv4 address to use as source address for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip4(struct Curl_easy *data,
|
||||
const char *local_ip4)
|
||||
{
|
||||
(void)data;
|
||||
@ -96,7 +96,7 @@ CURLcode Curl_set_dns_local_ip4(struct SessionHandle *data,
|
||||
* Function provided by the resolver backend to set
|
||||
* local IPv6 address to use as source address for DNS requests
|
||||
*/
|
||||
CURLcode Curl_set_dns_local_ip6(struct SessionHandle *data,
|
||||
CURLcode Curl_set_dns_local_ip6(struct Curl_easy *data,
|
||||
const char *local_ip6)
|
||||
{
|
||||
(void)data;
|
||||
|
@ -53,7 +53,6 @@
|
||||
#include "progress.h"
|
||||
#include "curl_base64.h"
|
||||
#include "cookie.h"
|
||||
#include "strequal.h"
|
||||
#include "vauth/vauth.h"
|
||||
#include "vtls/vtls.h"
|
||||
#include "http_digest.h"
|
||||
@ -68,7 +67,7 @@
|
||||
#include "parsedate.h" /* for the week day and month names */
|
||||
#include "strtoofft.h"
|
||||
#include "multiif.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "content_encoding.h"
|
||||
#include "http_proxy.h"
|
||||
#include "warnless.h"
|
||||
@ -77,6 +76,7 @@
|
||||
#include "pipeline.h"
|
||||
#include "http2.h"
|
||||
#include "connect.h"
|
||||
#include "strdup.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -151,7 +151,7 @@ const struct Curl_handler Curl_handler_https = {
|
||||
|
||||
CURLcode Curl_http_setup_conn(struct connectdata *conn)
|
||||
{
|
||||
/* allocate the HTTP-specific struct for the SessionHandle, only to survive
|
||||
/* allocate the HTTP-specific struct for the Curl_easy, only to survive
|
||||
during this request */
|
||||
struct HTTP *http;
|
||||
DEBUGASSERT(conn->data->req.protop == NULL);
|
||||
@ -179,10 +179,10 @@ char *Curl_checkheaders(const struct connectdata *conn,
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
for(head = data->set.headers;head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
if(strncasecompare(head->data, thisheader, thislen))
|
||||
return head->data;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ char *Curl_checkheaders(const struct connectdata *conn,
|
||||
* if proxy headers are not available, then it will lookup into http header
|
||||
* link list
|
||||
*
|
||||
* It takes a connectdata struct as input instead of the SessionHandle simply
|
||||
* It takes a connectdata struct as input instead of the Curl_easy simply
|
||||
* to know if this is a proxy request or not, as it then might check a
|
||||
* different header list.
|
||||
*/
|
||||
@ -203,12 +203,12 @@ char *Curl_checkProxyheaders(const struct connectdata *conn,
|
||||
{
|
||||
struct curl_slist *head;
|
||||
size_t thislen = strlen(thisheader);
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
|
||||
for(head = (conn->bits.proxy && data->set.sep_headers) ?
|
||||
data->set.proxyheaders : data->set.headers;
|
||||
head; head=head->next) {
|
||||
if(Curl_raw_nequal(head->data, thisheader, thislen))
|
||||
if(strncasecompare(head->data, thisheader, thislen))
|
||||
return head->data;
|
||||
}
|
||||
|
||||
@ -280,7 +280,7 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
{
|
||||
size_t size = 0;
|
||||
char *authorization = NULL;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
char **userp;
|
||||
const char *user;
|
||||
const char *pwd;
|
||||
@ -288,8 +288,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
|
||||
if(proxy) {
|
||||
userp = &conn->allocptr.proxyuserpwd;
|
||||
user = conn->proxyuser;
|
||||
pwd = conn->proxypasswd;
|
||||
user = conn->http_proxy.user;
|
||||
pwd = conn->http_proxy.passwd;
|
||||
}
|
||||
else {
|
||||
userp = &conn->allocptr.userpwd;
|
||||
@ -297,7 +297,8 @@ static CURLcode http_output_basic(struct connectdata *conn, bool proxy)
|
||||
pwd = conn->passwd;
|
||||
}
|
||||
|
||||
snprintf(data->state.buffer, sizeof(data->state.buffer), "%s:%s", user, pwd);
|
||||
snprintf(data->state.buffer, CURL_BUFSIZE(data->set.buffer_size),
|
||||
"%s:%s", user, pwd);
|
||||
|
||||
result = Curl_base64_encode(data,
|
||||
data->state.buffer, strlen(data->state.buffer),
|
||||
@ -377,7 +378,7 @@ static bool pickoneauth(struct auth *pick)
|
||||
*/
|
||||
static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct HTTP *http = data->req.protop;
|
||||
curl_off_t bytessent;
|
||||
curl_off_t expectsend = -1; /* default is unknown */
|
||||
@ -462,7 +463,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
#endif
|
||||
|
||||
/* This is not NTLM or many bytes left to send: close */
|
||||
connclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
streamclose(conn, "Mid-auth HTTP and much data left to send");
|
||||
data->req.size = 0; /* don't download any more than 0 bytes */
|
||||
|
||||
/* There still is data left to send, but this connection is marked for
|
||||
@ -485,7 +486,7 @@ static CURLcode http_perhapsrewind(struct connectdata *conn)
|
||||
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
bool pickhost = FALSE;
|
||||
bool pickproxy = FALSE;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -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
|
||||
|
@ -69,7 +69,7 @@ CURLcode Curl_add_buffer_send(Curl_send_buffer *in,
|
||||
size_t included_body_bytes,
|
||||
int socketindex);
|
||||
|
||||
CURLcode Curl_add_timecondition(struct SessionHandle *data,
|
||||
CURLcode Curl_add_timecondition(struct Curl_easy *data,
|
||||
Curl_send_buffer *buf);
|
||||
CURLcode Curl_add_custom_headers(struct connectdata *conn,
|
||||
bool is_connect,
|
||||
@ -87,7 +87,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn, char *datap,
|
||||
ssize_t length, ssize_t *wrote);
|
||||
|
||||
/* These functions are in http.c */
|
||||
void Curl_http_auth_stage(struct SessionHandle *data, int stage);
|
||||
void Curl_http_auth_stage(struct Curl_easy *data, int stage);
|
||||
CURLcode Curl_http_input_auth(struct connectdata *conn, bool proxy,
|
||||
const char *auth);
|
||||
CURLcode Curl_http_auth_act(struct connectdata *conn);
|
||||
@ -168,6 +168,7 @@ struct HTTP {
|
||||
const uint8_t *pausedata; /* pointer to data received in on_data_chunk */
|
||||
size_t pauselen; /* the number of bytes left in data */
|
||||
bool closed; /* TRUE on HTTP2 stream close */
|
||||
bool close_handled; /* TRUE if stream closure is handled by libcurl */
|
||||
uint32_t error_code; /* HTTP/2 error code */
|
||||
|
||||
char *mem; /* points to a buffer in memory to store received data */
|
||||
@ -216,14 +217,18 @@ struct http_conn {
|
||||
nghttp2_session_mem_recv */
|
||||
size_t drain_total; /* sum of all stream's UrlState.drain */
|
||||
|
||||
/* this is a hash of all individual streams (SessionHandle structs) */
|
||||
/* this is a hash of all individual streams (Curl_easy structs) */
|
||||
struct h2settings settings;
|
||||
|
||||
/* list of settings that will be sent */
|
||||
nghttp2_settings_entry local_settings[3];
|
||||
size_t local_settings_num;
|
||||
#else
|
||||
int unused; /* prevent a compiler warning */
|
||||
#endif
|
||||
};
|
||||
|
||||
CURLcode Curl_http_readwrite_headers(struct SessionHandle *data,
|
||||
CURLcode Curl_http_readwrite_headers(struct Curl_easy *data,
|
||||
struct connectdata *conn,
|
||||
ssize_t *nread,
|
||||
bool *stop_reading);
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -29,13 +29,13 @@
|
||||
#include "http.h"
|
||||
#include "sendf.h"
|
||||
#include "curl_base64.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "multiif.h"
|
||||
#include "conncache.h"
|
||||
#include "url.h"
|
||||
#include "connect.h"
|
||||
#include "strtoofft.h"
|
||||
|
||||
#include "strdup.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
@ -59,6 +59,12 @@
|
||||
#define nghttp2_session_callbacks_set_error_callback(x,y)
|
||||
#endif
|
||||
|
||||
#if (NGHTTP2_VERSION_NUM >= 0x010c00)
|
||||
#define NGHTTP2_HAS_SET_LOCAL_WINDOW_SIZE 1
|
||||
#endif
|
||||
|
||||
#define HTTP2_HUGE_WINDOW_SIZE (1 << 30)
|
||||
|
||||
/*
|
||||
* Curl_http2_init_state() is called when the easy handle is created and
|
||||
* allows for HTTP/2 specific init of state.
|
||||
@ -92,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. */
|
||||
|
@ -7,7 +7,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -50,7 +50,14 @@ CURLcode Curl_http2_switched(struct connectdata *conn,
|
||||
const char *data, size_t nread);
|
||||
/* called from Curl_http_setup_conn */
|
||||
void Curl_http2_setup_conn(struct connectdata *conn);
|
||||
void Curl_http2_setup_req(struct SessionHandle *data);
|
||||
void Curl_http2_setup_req(struct Curl_easy *data);
|
||||
void Curl_http2_done(struct connectdata *conn, bool premature);
|
||||
CURLcode Curl_http2_done_sending(struct connectdata *conn);
|
||||
void Curl_http2_add_child(struct Curl_easy *parent, struct Curl_easy *child,
|
||||
bool exclusive);
|
||||
void Curl_http2_remove_child(struct Curl_easy *parent,
|
||||
struct Curl_easy *child);
|
||||
void Curl_http2_cleanup_dependencies(struct Curl_easy *data);
|
||||
#else /* USE_NGHTTP2 */
|
||||
#define Curl_http2_init(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
#define Curl_http2_send_request(x) CURLE_UNSUPPORTED_PROTOCOL
|
||||
@ -61,6 +68,11 @@ void Curl_http2_setup_req(struct SessionHandle *data);
|
||||
#define Curl_http2_setup_req(x)
|
||||
#define Curl_http2_init_state(x)
|
||||
#define Curl_http2_init_userset(x)
|
||||
#define Curl_http2_done(x,y)
|
||||
#define Curl_http2_done_sending(x)
|
||||
#define Curl_http2_add_child(x, y, z)
|
||||
#define Curl_http2_remove_child(x, y)
|
||||
#define Curl_http2_cleanup_dependencies(x)
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP2_H */
|
||||
|
@ -108,7 +108,7 @@ CHUNKcode Curl_httpchunk_read(struct connectdata *conn,
|
||||
ssize_t *wrotep)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct Curl_easy *data = conn->data;
|
||||
struct Curl_chunker *ch = &conn->chunk;
|
||||
struct SingleRequest *k = &data->req;
|
||||
size_t piece;
|
||||
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -34,7 +34,7 @@ CURLcode Curl_output_digest(struct connectdata *conn,
|
||||
const unsigned char *uripath);
|
||||
|
||||
#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_CRYPTO_AUTH)
|
||||
void Curl_digest_cleanup(struct SessionHandle *data);
|
||||
void Curl_digest_cleanup(struct Curl_easy *data);
|
||||
#else
|
||||
#define Curl_digest_cleanup(x) Curl_nop_stmt
|
||||
#endif
|
||||
|
@ -26,7 +26,6 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "http_negotiate.h"
|
||||
#include "vauth/vauth.h"
|
||||
|
||||
@ -38,7 +37,8 @@
|
||||
CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
const char *header)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
CURLcode result;
|
||||
struct Curl_easy *data = conn->data;
|
||||
size_t len;
|
||||
|
||||
/* Point to the username, password, service and host */
|
||||
@ -51,11 +51,11 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
struct negotiatedata *neg_ctx;
|
||||
|
||||
if(proxy) {
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
service = data->set.str[STRING_PROXY_SERVICE_NAME] ?
|
||||
data->set.str[STRING_PROXY_SERVICE_NAME] : "HTTP";
|
||||
host = conn->proxy.name;
|
||||
host = conn->http_proxy.host.name;
|
||||
neg_ctx = &data->state.proxyneg;
|
||||
}
|
||||
else {
|
||||
@ -90,8 +90,13 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
}
|
||||
|
||||
/* Initilise the security context and decode our challenge */
|
||||
return Curl_auth_decode_spnego_message(data, userp, passwdp, service, host,
|
||||
header, neg_ctx);
|
||||
result = Curl_auth_decode_spnego_message(data, userp, passwdp, service,
|
||||
host, header, neg_ctx);
|
||||
|
||||
if(result)
|
||||
Curl_auth_spnego_cleanup(neg_ctx);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
@ -124,7 +129,7 @@ CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy)
|
||||
return (userp == NULL) ? CURLE_OUT_OF_MEMORY : CURLE_OK;
|
||||
}
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data)
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data)
|
||||
{
|
||||
Curl_auth_spnego_cleanup(&data->state.negotiate);
|
||||
Curl_auth_spnego_cleanup(&data->state.proxyneg);
|
||||
|
@ -31,7 +31,7 @@ CURLcode Curl_input_negotiate(struct connectdata *conn, bool proxy,
|
||||
/* this is for creating Negotiate header output */
|
||||
CURLcode Curl_output_negotiate(struct connectdata *conn, bool proxy);
|
||||
|
||||
void Curl_cleanup_negotiate(struct SessionHandle *data);
|
||||
void Curl_cleanup_negotiate(struct Curl_easy *data);
|
||||
|
||||
#endif /* USE_SPNEGO */
|
||||
|
||||
|
@ -27,7 +27,7 @@
|
||||
/*
|
||||
* NTLM details:
|
||||
*
|
||||
* http://davenport.sourceforge.net/ntlm.html
|
||||
* https://davenport.sourceforge.io/ntlm.html
|
||||
* https://www.innovation.ch/java/ntlm.html
|
||||
*/
|
||||
|
||||
@ -35,7 +35,7 @@
|
||||
|
||||
#include "urldata.h"
|
||||
#include "sendf.h"
|
||||
#include "rawstr.h"
|
||||
#include "strcase.h"
|
||||
#include "http_ntlm.h"
|
||||
#include "curl_ntlm_wb.h"
|
||||
#include "vauth/vauth.h"
|
||||
@ -136,8 +136,8 @@ CURLcode Curl_output_ntlm(struct connectdata *conn, bool proxy)
|
||||
|
||||
if(proxy) {
|
||||
allocuserpwd = &conn->allocptr.proxyuserpwd;
|
||||
userp = conn->proxyuser;
|
||||
passwdp = conn->proxypasswd;
|
||||
userp = conn->http_proxy.user;
|
||||
passwdp = conn->http_proxy.passwd;
|
||||
ntlm = &conn->proxyntlm;
|
||||
authp = &conn->data->state.authproxy;
|
||||
}
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -31,19 +31,54 @@
|
||||
#include "http.h"
|
||||
#include "url.h"
|
||||
#include "select.h"
|
||||
#include "rawstr.h"
|
||||
#include "progress.h"
|
||||
#include "non-ascii.h"
|
||||
#include "connect.h"
|
||||
#include "curlx.h"
|
||||
#include "vtls/vtls.h"
|
||||
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
#include "curl_memory.h"
|
||||
#include "memdebug.h"
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn)
|
||||
/*
|
||||
* Perform SSL initialization for HTTPS proxy. Sets
|
||||
* proxy_ssl_connected connection bit when complete. Can be
|
||||
* called multiple times.
|
||||
*/
|
||||
static CURLcode https_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
#ifdef USE_SSL
|
||||
CURLcode result = CURLE_OK;
|
||||
DEBUGASSERT(conn->http_proxy.proxytype == CURLPROXY_HTTPS);
|
||||
if(!conn->bits.proxy_ssl_connected[sockindex]) {
|
||||
/* perform SSL initialization for this socket */
|
||||
result =
|
||||
Curl_ssl_connect_nonblocking(conn, sockindex,
|
||||
&conn->bits.proxy_ssl_connected[sockindex]);
|
||||
if(result)
|
||||
conn->bits.close = TRUE; /* a failed connection is marked for closure to
|
||||
prevent (bad) re-use or similar */
|
||||
}
|
||||
return result;
|
||||
#else
|
||||
(void) conn;
|
||||
(void) sockindex;
|
||||
return CURLE_NOT_BUILT_IN;
|
||||
#endif
|
||||
}
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex)
|
||||
{
|
||||
if(conn->http_proxy.proxytype == CURLPROXY_HTTPS) {
|
||||
const CURLcode result = https_proxy_connect(conn, sockindex);
|
||||
if(result)
|
||||
return result;
|
||||
if(!conn->bits.proxy_ssl_connected[sockindex])
|
||||
return result; /* wait for HTTPS proxy SSL initialization to complete */
|
||||
}
|
||||
|
||||
if(conn->bits.tunnel_proxy && conn->bits.httpproxy) {
|
||||
#ifndef CURL_DISABLE_PROXY
|
||||
/* for [protocol] tunneled through HTTP proxy */
|
||||
@ -63,21 +98,31 @@ CURLcode Curl_proxy_connect(struct connectdata *conn)
|
||||
* original pointer
|
||||
*
|
||||
* This function might be called several times in the multi interface case
|
||||
* if the proxy's CONNTECT response is not instant.
|
||||
* if the proxy's CONNECT response is not instant.
|
||||
*/
|
||||
prot_save = conn->data->req.protop;
|
||||
memset(&http_proxy, 0, sizeof(http_proxy));
|
||||
conn->data->req.protop = &http_proxy;
|
||||
connkeep(conn, "HTTP proxy CONNECT");
|
||||
|
||||
/* for the secondary socket (FTP), use the "connect to host"
|
||||
* but ignore the "connect to port" (use the secondary port)
|
||||
*/
|
||||
|
||||
if(conn->bits.conn_to_host)
|
||||
hostname = conn->conn_to_host.name;
|
||||
else if(sockindex == SECONDARYSOCKET)
|
||||
hostname = conn->secondaryhostname;
|
||||
else
|
||||
hostname = conn->host.name;
|
||||
if(conn->bits.conn_to_port)
|
||||
|
||||
if(sockindex == SECONDARYSOCKET)
|
||||
remote_port = conn->secondary_port;
|
||||
else if(conn->bits.conn_to_port)
|
||||
remote_port = conn->conn_to_port;
|
||||
else
|
||||
remote_port = conn->remote_port;
|
||||
result = Curl_proxyCONNECT(conn, FIRSTSOCKET, hostname,
|
||||
result = Curl_proxyCONNECT(conn, sockindex, hostname,
|
||||
remote_port, FALSE);
|
||||
conn->data->req.protop = prot_save;
|
||||
if(CURLE_OK != result)
|
||||
@ -107,14 +152,14 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
bool blocking)
|
||||
{
|
||||
int subversion=0;
|
||||
struct SessionHandle *data=conn->data;
|
||||
struct Curl_easy *data=conn->data;
|
||||
struct SingleRequest *k = &data->req;
|
||||
CURLcode result;
|
||||
curl_socket_t tunnelsocket = conn->sock[sockindex];
|
||||
curl_off_t cl=0;
|
||||
bool closeConnection = FALSE;
|
||||
bool chunked_encoding = FALSE;
|
||||
long check;
|
||||
time_t check;
|
||||
|
||||
#define SELECT_OK 0
|
||||
#define SELECT_ERROR 1
|
||||
@ -159,9 +204,10 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
free(host_port);
|
||||
|
||||
if(!result) {
|
||||
char *host=(char *)"";
|
||||
char *host = NULL;
|
||||
const char *proxyconn="";
|
||||
const char *useragent="";
|
||||
const char *http = (conn->proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
const char *http = (conn->http_proxy.proxytype == CURLPROXY_HTTP_1_0) ?
|
||||
"1.0" : "1.1";
|
||||
bool ipv6_ip = conn->bits.ipv6_ip;
|
||||
char *hostheader;
|
||||
@ -185,6 +231,9 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
return CURLE_OUT_OF_MEMORY;
|
||||
}
|
||||
}
|
||||
if(!Curl_checkProxyheaders(conn, "Proxy-Connection:"))
|
||||
proxyconn = "Proxy-Connection: Keep-Alive\r\n";
|
||||
|
||||
if(!Curl_checkProxyheaders(conn, "User-Agent:") &&
|
||||
data->set.str[STRING_USERAGENT])
|
||||
useragent = conn->allocptr.uagent;
|
||||
@ -194,15 +243,17 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
"CONNECT %s HTTP/%s\r\n"
|
||||
"%s" /* Host: */
|
||||
"%s" /* Proxy-Authorization */
|
||||
"%s", /* User-Agent */
|
||||
"%s" /* User-Agent */
|
||||
"%s", /* Proxy-Connection */
|
||||
hostheader,
|
||||
http,
|
||||
host,
|
||||
host?host:"",
|
||||
conn->allocptr.proxyuserpwd?
|
||||
conn->allocptr.proxyuserpwd:"",
|
||||
useragent);
|
||||
useragent,
|
||||
proxyconn);
|
||||
|
||||
if(host && *host)
|
||||
if(host)
|
||||
free(host);
|
||||
free(hostheader);
|
||||
|
||||
@ -239,7 +290,7 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(!blocking) {
|
||||
if(0 == Curl_socket_ready(tunnelsocket, CURL_SOCKET_BAD, 0))
|
||||
if(!Curl_conn_data_pending(conn, sockindex))
|
||||
/* return so we'll be called again polling-style */
|
||||
return CURLE_OK;
|
||||
else {
|
||||
@ -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 */
|
||||
|
@ -32,11 +32,11 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
/* Default proxy timeout in milliseconds */
|
||||
#define PROXY_TIMEOUT (3600*1000)
|
||||
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn);
|
||||
CURLcode Curl_proxy_connect(struct connectdata *conn, int sockindex);
|
||||
|
||||
#else
|
||||
#define Curl_proxyCONNECT(x,y,z,w,v) CURLE_NOT_BUILT_IN
|
||||
#define Curl_proxy_connect(x) CURLE_OK
|
||||
#define Curl_proxy_connect(x,y) CURLE_OK
|
||||
#endif
|
||||
|
||||
#endif /* HEADER_CURL_HTTP_PROXY_H */
|
||||
|
@ -51,7 +51,7 @@
|
||||
#endif
|
||||
|
||||
#include "inet_ntop.h"
|
||||
#include "strequal.h"
|
||||
#include "strcase.h"
|
||||
#include "if2ip.h"
|
||||
/* The last 3 #include files should be in this order */
|
||||
#include "curl_printf.h"
|
||||
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
@ -1,53 +0,0 @@
|
||||
;
|
||||
; Definition file for the DLL version of the LIBCURL library from curl
|
||||
;
|
||||
|
||||
LIBRARY LIBCURL
|
||||
|
||||
;DESCRIPTION 'curl libcurl - https://curl.haxx.se'
|
||||
|
||||
EXPORTS
|
||||
curl_easy_cleanup @ 1 ;
|
||||
curl_easy_getinfo @ 2 ;
|
||||
curl_easy_init @ 3 ;
|
||||
curl_easy_perform @ 4 ;
|
||||
curl_easy_setopt @ 5 ;
|
||||
curl_escape @ 6 ;
|
||||
curl_unescape @ 7;
|
||||
curl_formfree @ 9 ;
|
||||
curl_getdate @ 10 ;
|
||||
curl_getenv @ 11 ;
|
||||
curl_global_cleanup @ 12 ;
|
||||
curl_global_init @ 13 ;
|
||||
curl_slist_append @ 14 ;
|
||||
curl_slist_free_all @ 15 ;
|
||||
curl_version @ 16 ;
|
||||
curl_maprintf @ 17 ;
|
||||
curl_mfprintf @ 18 ;
|
||||
curl_mprintf @ 19 ;
|
||||
curl_msprintf @ 20 ;
|
||||
curl_msnprintf @ 21 ;
|
||||
curl_mvfprintf @ 22 ;
|
||||
curl_strequal @ 23 ;
|
||||
curl_strnequal @ 24 ;
|
||||
curl_easy_duphandle @ 25 ;
|
||||
curl_formadd @ 26 ;
|
||||
curl_multi_init @ 27;
|
||||
curl_multi_add_handle @ 28;
|
||||
curl_multi_remove_handle @ 29;
|
||||
curl_multi_fdset @ 30;
|
||||
curl_multi_perform @ 31;
|
||||
curl_multi_cleanup @ 32;
|
||||
curl_multi_info_read @ 33;
|
||||
curl_free @ 34;
|
||||
curl_version_info @ 35;
|
||||
curl_share_init @ 36;
|
||||
curl_share_setopt @ 37;
|
||||
curl_share_cleanup @ 38;
|
||||
curl_global_init_mem @ 39;
|
||||
curl_easy_strerror @ 40;
|
||||
curl_multi_strerror @ 41;
|
||||
curl_share_strerror @ 42;
|
||||
curl_easy_reset @ 43;
|
||||
curl_mvsnprintf @ 44 ;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* | (__| |_| | _ <| |___
|
||||
* \___|\___/|_| \_\_____|
|
||||
*
|
||||
* Copyright (C) 1998 - 2009, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
* Copyright (C) 1998 - 2017, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||
*
|
||||
* This software is licensed as described in the file COPYING, which
|
||||
* you should have received as part of this distribution. The terms
|
||||
@ -44,14 +44,14 @@ BEGIN
|
||||
BEGIN
|
||||
BLOCK "040904b0"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "The cURL library, https://curl.haxx.se/\0"
|
||||
VALUE "CompanyName", "The curl library, https://curl.haxx.se/\0"
|
||||
VALUE "FileDescription", "libcurl Shared Library\0"
|
||||
VALUE "FileVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "InternalName", "libcurl\0"
|
||||
VALUE "OriginalFilename", "libcurl.dll\0"
|
||||
VALUE "ProductName", "The cURL library\0"
|
||||
VALUE "ProductName", "The curl library\0"
|
||||
VALUE "ProductVersion", LIBCURL_VERSION "\0"
|
||||
VALUE "LegalCopyright", "© " LIBCURL_COPYRIGHT "\0"
|
||||
VALUE "LegalCopyright", "\xa9 " LIBCURL_COPYRIGHT "\0" /* a9: Copyright symbol */
|
||||
VALUE "License", "https://curl.haxx.se/docs/copyright.html\0"
|
||||
END
|
||||
END
|
||||
|
@ -213,7 +213,8 @@ static void MD4_Update(MD4_CTX *ctx, const void *data, unsigned long size)
|
||||
unsigned long used, available;
|
||||
|
||||
saved_lo = ctx->lo;
|
||||
if((ctx->lo = (saved_lo + size) & 0x1fffffff) < saved_lo)
|
||||
ctx->lo = (saved_lo + size) & 0x1fffffff;
|
||||
if(ctx->lo < saved_lo)
|
||||
ctx->hi++;
|
||||
ctx->hi += (MD4_u32plus)size >> 29;
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user