aboutsummaryrefslogtreecommitdiff
path: root/lib/url.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/url.c')
-rw-r--r--lib/url.c302
1 files changed, 187 insertions, 115 deletions
diff --git a/lib/url.c b/lib/url.c
index c5b642fde..40dcd1568 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -20,30 +20,14 @@
*
***************************************************************************/
-/* -- WIN32 approved -- */
-
#include "setup.h"
-#include <stdio.h>
-#include <string.h>
-#include <stdarg.h>
-#include <stdlib.h>
-#include <ctype.h>
-#include <errno.h>
-
-#ifdef WIN32
-#include <time.h>
-#include <io.h>
-#else
#ifdef HAVE_SYS_SOCKET_H
#include <sys/socket.h>
#endif
#ifdef HAVE_NETINET_IN_H
#include <netinet/in.h>
#endif
-#ifdef HAVE_SYS_TIME_H
-#include <sys/time.h>
-#endif
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
@@ -73,8 +57,6 @@
#error "We can't compile without socket() support!"
#endif
-#endif /* WIN32 */
-
#ifdef HAVE_LIMITS_H
#include <limits.h>
#endif
@@ -137,7 +119,8 @@ int curl_win32_idn_to_ascii(const char *in, char **out);
#include "url.h"
#include "connect.h"
#include "inet_ntop.h"
-#include "http_ntlm.h"
+#include "curl_ntlm.h"
+#include "curl_ntlm_wb.h"
#include "socks.h"
#include "curl_rtmp.h"
#include "gopher.h"
@@ -153,6 +136,7 @@ int curl_win32_idn_to_ascii(const char *in, char **out);
static long ConnectionKillOne(struct SessionHandle *data);
static void conn_free(struct connectdata *conn);
static void signalPipeClose(struct curl_llist *pipeline, bool pipe_broke);
+static CURLcode do_init(struct connectdata *conn);
/*
* Protocol table.
@@ -262,6 +246,7 @@ static const struct Curl_handler Curl_handler_dummy = {
ZERO_NULL, /* doing */
ZERO_NULL, /* proto_getsock */
ZERO_NULL, /* doing_getsock */
+ ZERO_NULL, /* domore_getsock */
ZERO_NULL, /* perform_getsock */
ZERO_NULL, /* disconnect */
ZERO_NULL, /* readwrite */
@@ -270,12 +255,6 @@ static const struct Curl_handler Curl_handler_dummy = {
PROTOPT_NONE /* flags */
};
-void Curl_safefree(void *ptr)
-{
- if(ptr)
- free(ptr);
-}
-
static void close_connections(struct SessionHandle *data)
{
/* Loop through all open connections and kill them one by one */
@@ -298,10 +277,7 @@ static CURLcode setstropt(char **charp, char * s)
/* Release the previous storage at `charp' and replace by a dynamic storage
copy of `s'. Return CURLE_OK or CURLE_OUT_OF_MEMORY. */
- if(*charp) {
- free(*charp);
- *charp = (char *) NULL;
- }
+ Curl_safefree(*charp);
if(s) {
s = strdup(s);
@@ -480,6 +456,7 @@ CURLcode Curl_close(struct SessionHandle *data)
/* free the connection cache if allocated privately */
Curl_rm_connc(data->state.connc);
+ data->state.connc = NULL;
}
}
@@ -501,6 +478,8 @@ CURLcode Curl_close(struct SessionHandle *data)
/* Free the pathbuffer */
Curl_safefree(data->state.pathbuffer);
+ data->state.path = NULL;
+
Curl_safefree(data->state.proto.generic);
/* Close down all open SSL info and sessions */
@@ -509,11 +488,17 @@ CURLcode Curl_close(struct SessionHandle *data)
Curl_safefree(data->state.scratch);
Curl_ssl_free_certinfo(data);
- if(data->change.referer_alloc)
- free(data->change.referer);
+ if(data->change.referer_alloc) {
+ Curl_safefree(data->change.referer);
+ data->change.referer_alloc = FALSE;
+ }
+ data->change.referer = NULL;
- if(data->change.url_alloc)
- free(data->change.url);
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+ data->change.url = NULL;
Curl_safefree(data->state.headerbuff);
@@ -640,13 +625,19 @@ CURLcode Curl_ch_connc(struct SessionHandle *data,
curl_multi_cleanup(). */
void Curl_rm_connc(struct conncache *c)
{
+ if(!c)
+ return;
+
if(c->connects) {
long i;
- for(i = 0; i < c->num; ++i)
+ for(i = 0; i < c->num; ++i) {
conn_free(c->connects[i]);
-
+ c->connects[i] = NULL;
+ }
free(c->connects);
+ c->connects = NULL;
}
+ c->num = 0;
free(c);
}
@@ -844,7 +835,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
{
/* remember we want this enabled */
long use_cache = va_arg(param, long);
- data->set.global_dns_cache = (bool)(0 != use_cache);
+ data->set.global_dns_cache = (0 != use_cache)?TRUE:FALSE;
}
break;
case CURLOPT_SSL_CIPHER_LIST:
@@ -880,33 +871,33 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* When this transfer is done, it must not be left to be reused by a
* subsequent transfer but shall be closed immediately.
*/
- data->set.reuse_forbid = (bool)(0 != va_arg(param, long));
+ data->set.reuse_forbid = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FRESH_CONNECT:
/*
* This transfer shall not use a previously cached connection but
* should be made with a fresh new connect!
*/
- data->set.reuse_fresh = (bool)(0 != va_arg(param, long));
+ data->set.reuse_fresh = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_VERBOSE:
/*
* Verbose means infof() calls that give a lot of information about
* the connection and transfer procedures as well as internal choices.
*/
- data->set.verbose = (bool)(0 != va_arg(param, long));
+ data->set.verbose = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_HEADER:
/*
* Set to include the header in the general data output stream.
*/
- data->set.include_header = (bool)(0 != va_arg(param, long));
+ data->set.include_header = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_NOPROGRESS:
/*
* Shut off the internal supported progress meter
*/
- data->set.hide_progress = (bool)(0 != va_arg(param, long));
+ data->set.hide_progress = (0 != va_arg(param, long))?TRUE:FALSE;
if(data->set.hide_progress)
data->progress.flags |= PGRS_HIDE;
else
@@ -916,14 +907,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/*
* Do not include the body part in the output data stream.
*/
- data->set.opt_no_body = (bool)(0 != va_arg(param, long));
+ data->set.opt_no_body = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FAILONERROR:
/*
* Don't output the >=300 error code HTML-page, but instead only
* return error.
*/
- data->set.http_fail_on_error = (bool)(0 != va_arg(param, long));
+ data->set.http_fail_on_error = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_UPLOAD:
case CURLOPT_PUT:
@@ -931,7 +922,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* We want to sent data to the remote host. If this is HTTP, that equals
* using the PUT request.
*/
- data->set.upload = (bool)(0 != va_arg(param, long));
+ data->set.upload = (0 != va_arg(param, long))?TRUE:FALSE;
if(data->set.upload) {
/* If this is HTTP, PUT is what's needed to "upload" */
data->set.httpreq = HTTPREQ_PUT;
@@ -947,7 +938,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* Try to get the file time of the remote document. The time will
* later (possibly) become available using curl_easy_getinfo().
*/
- data->set.get_filetime = (bool)(0 != va_arg(param, long));
+ data->set.get_filetime = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FTP_CREATE_MISSING_DIRS:
/*
@@ -988,13 +979,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* An option that changes the command to one that asks for a list
* only, no file info details.
*/
- data->set.ftp_list_only = (bool)(0 != va_arg(param, long));
+ data->set.ftp_list_only = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_APPEND:
/*
* We want to upload and append to an existing file.
*/
- data->set.ftp_append = (bool)(0 != va_arg(param, long));
+ data->set.ftp_append = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FTP_FILEMETHOD:
/*
@@ -1022,7 +1013,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
*
* Transfer using ASCII (instead of BINARY).
*/
- data->set.prefer_ascii = (bool)(0 != va_arg(param, long));
+ data->set.prefer_ascii = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_TIMECONDITION:
/*
@@ -1051,7 +1042,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/*
* Switch on automatic referer that gets set if curl follows locations.
*/
- data->set.http_auto_referer = (bool)(0 != va_arg(param, long));
+ data->set.http_auto_referer = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_ACCEPT_ENCODING:
@@ -1071,14 +1062,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
break;
case CURLOPT_TRANSFER_ENCODING:
- data->set.http_transfer_encoding = (bool)(0 != va_arg(param, long));
+ data->set.http_transfer_encoding = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FOLLOWLOCATION:
/*
* Follow Location: header hints on a HTTP-server.
*/
- data->set.http_follow_location = (bool)(0 != va_arg(param, long));
+ data->set.http_follow_location = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_UNRESTRICTED_AUTH:
@@ -1087,7 +1078,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* hostname changed.
*/
data->set.http_disable_hostname_check_before_authentication =
- (bool)(0 != va_arg(param, long));
+ (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_MAXREDIRS:
@@ -1109,8 +1100,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* other - POST is kept as POST after 301 and 302
*/
long postRedir = va_arg(param, long);
- data->set.post301 = (bool)((postRedir & CURL_REDIR_POST_301)?TRUE:FALSE);
- data->set.post302 = (bool)((postRedir & CURL_REDIR_POST_302)?TRUE:FALSE);
+ data->set.post301 = (postRedir & CURL_REDIR_POST_301)?TRUE:FALSE;
+ data->set.post302 = (postRedir & CURL_REDIR_POST_302)?TRUE:FALSE;
}
break;
@@ -1231,7 +1222,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* String to set in the HTTP Referer: field.
*/
if(data->change.referer_alloc) {
- free(data->change.referer);
+ Curl_safefree(data->change.referer);
data->change.referer_alloc = FALSE;
}
result = setstropt(&data->set.str[STRING_SET_REFERER],
@@ -1280,10 +1271,11 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/* append the cookie file name to the list of file names, and deal with
them later */
cl = curl_slist_append(data->change.cookielist, argptr);
-
- if(!cl)
+ if(!cl) {
+ curl_slist_free_all(data->change.cookielist);
+ data->change.cookielist = NULL;
return CURLE_OUT_OF_MEMORY;
-
+ }
data->change.cookielist = cl; /* store the list for later use */
}
break;
@@ -1319,7 +1311,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* We run mostly with the original cookie spec, as hardly anyone implements
* anything else.
*/
- data->set.cookiesession = (bool)(0 != va_arg(param, long));
+ data->set.cookiesession = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_COOKIELIST:
@@ -1394,8 +1386,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/* the DIGEST_IE bit is only used to set a special marker, for all the
rest we need to handle it as normal DIGEST */
- data->state.authhost.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?
- TRUE:FALSE);
+ data->state.authhost.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
if(auth & CURLAUTH_DIGEST_IE) {
auth |= CURLAUTH_DIGEST; /* set standard digest bit */
@@ -1404,7 +1395,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/* switch off bits we can't support */
#ifndef USE_NTLM
- auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
+ auth &= ~CURLAUTH_NTLM; /* no NTLM support */
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
#endif
#ifndef USE_HTTP_NEGOTIATE
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
@@ -1437,7 +1431,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/*
* Tunnel operations through the proxy instead of normal proxy use
*/
- data->set.tunnel_thru_httpproxy = (bool)(0 != va_arg(param, long));
+ data->set.tunnel_thru_httpproxy = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_PROXYPORT:
@@ -1456,8 +1450,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/* the DIGEST_IE bit is only used to set a special marker, for all the
rest we need to handle it as normal DIGEST */
- data->state.authproxy.iestyle = (bool)((auth & CURLAUTH_DIGEST_IE)?
- TRUE:FALSE);
+ data->state.authproxy.iestyle = (auth & CURLAUTH_DIGEST_IE)?TRUE:FALSE;
if(auth & CURLAUTH_DIGEST_IE) {
auth |= CURLAUTH_DIGEST; /* set standard digest bit */
@@ -1465,7 +1458,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
}
/* switch off bits we can't support */
#ifndef USE_NTLM
- auth &= ~CURLAUTH_NTLM; /* no NTLM without SSL */
+ auth &= ~CURLAUTH_NTLM; /* no NTLM support */
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
+#elif !defined(NTLM_WB_ENABLED)
+ auth &= ~CURLAUTH_NTLM_WB; /* no NTLM_WB support */
#endif
#ifndef USE_HTTP_NEGOTIATE
auth &= ~CURLAUTH_GSSNEGOTIATE; /* no GSS-Negotiate without GSSAPI or
@@ -1531,7 +1527,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/*
* set flag for nec socks5 support
*/
- data->set.socks5_gssapi_nec = (bool)(0 != va_arg(param, long));
+ data->set.socks5_gssapi_nec = (0 != va_arg(param, long))?TRUE:FALSE;
break;
#endif
@@ -1560,19 +1556,20 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
*/
result = setstropt(&data->set.str[STRING_FTPPORT],
va_arg(param, char *));
- data->set.ftp_use_port = (bool)(NULL != data->set.str[STRING_FTPPORT]);
+ data->set.ftp_use_port = (NULL != data->set.str[STRING_FTPPORT]) ?
+ TRUE:FALSE;
break;
case CURLOPT_FTP_USE_EPRT:
- data->set.ftp_use_eprt = (bool)(0 != va_arg(param, long));
+ data->set.ftp_use_eprt = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FTP_USE_EPSV:
- data->set.ftp_use_epsv = (bool)(0 != va_arg(param, long));
+ data->set.ftp_use_epsv = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FTP_USE_PRET:
- data->set.ftp_use_pret = (bool)(0 != va_arg(param, long));
+ data->set.ftp_use_pret = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FTP_SSL_CCC:
@@ -1584,7 +1581,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* Enable or disable FTP_SKIP_PASV_IP, which will disable/enable the
* bypass of the IP address in PASV responses.
*/
- data->set.ftp_skip_ip = (bool)(0 != va_arg(param, long));
+ data->set.ftp_skip_ip = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_INFILE:
@@ -1642,8 +1639,8 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
*/
if(data->change.url_alloc) {
/* the already set URL is allocated, free it first! */
- free(data->change.url);
- data->change.url_alloc=FALSE;
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
}
result = setstropt(&data->set.str[STRING_SET_URL],
va_arg(param, char *));
@@ -1954,7 +1951,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/*
* Kludgy option to enable CRLF conversions. Subject for removal.
*/
- data->set.crlf = (bool)(0 != va_arg(param, long));
+ data->set.crlf = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_INTERFACE:
@@ -1983,7 +1980,13 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
*/
result = setstropt(&data->set.str[STRING_KRB_LEVEL],
va_arg(param, char *));
- data->set.krb = (bool)(NULL != data->set.str[STRING_KRB_LEVEL]);
+ data->set.krb = (NULL != data->set.str[STRING_KRB_LEVEL])?TRUE:FALSE;
+ break;
+ case CURLOPT_GSSAPI_DELEGATION:
+ /*
+ * GSSAPI credential delegation
+ */
+ data->set.gssapi_delegation = va_arg(param, long);
break;
case CURLOPT_SSL_VERIFYPEER:
/*
@@ -2015,7 +2018,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->set.ssl.fsslctxp = va_arg(param, void *);
break;
case CURLOPT_CERTINFO:
- data->set.ssl.certinfo = (bool)(0 != va_arg(param, long));
+ data->set.ssl.certinfo = (0 != va_arg(param, long))?TRUE:FALSE;
break;
#endif
case CURLOPT_CAINFO:
@@ -2075,7 +2078,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* The application asks not to set any signal() or alarm() handlers,
* even when using a timeout.
*/
- data->set.no_signal = (bool)(0 != va_arg(param, long));
+ data->set.no_signal = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_SHARE:
@@ -2092,8 +2095,15 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->dns.hostcachetype = HCACHE_NONE;
}
+#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
if(data->share->cookies == data->cookies)
data->cookies = NULL;
+#endif
+
+ if(data->share->sslsession == data->state.session) {
+ data->state.session = NULL;
+ data->set.ssl.numsessions = 0;
+ }
data->share->dirty--;
@@ -2126,6 +2136,10 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
data->cookies = data->share->cookies;
}
#endif /* CURL_DISABLE_HTTP */
+ if(data->share->sslsession) {
+ data->set.ssl.numsessions = data->share->nsslsession;
+ data->state.session = data->share->sslsession;
+ }
Curl_share_unlock(data, CURL_LOCK_DATA_SHARE);
}
@@ -2179,7 +2193,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
* Enable or disable TCP_NODELAY, which will disable/enable the Nagle
* algorithm
*/
- data->set.tcp_nodelay = (bool)(0 != va_arg(param, long));
+ data->set.tcp_nodelay = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FTP_ACCOUNT:
@@ -2188,14 +2202,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
break;
case CURLOPT_IGNORE_CONTENT_LENGTH:
- data->set.ignorecl = (bool)(0 != va_arg(param, long));
+ data->set.ignorecl = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_CONNECT_ONLY:
/*
* No data transfer, set up connection and let application use the socket
*/
- data->set.connect_only = (bool)(0 != va_arg(param, long));
+ data->set.connect_only = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_FTP_ALTERNATIVE_TO_USER:
@@ -2248,7 +2262,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
break;
case CURLOPT_SSL_SESSIONID_CACHE:
- data->set.ssl.sessionid = (bool)(0 != va_arg(param, long));
+ data->set.ssl.sessionid = (0 != va_arg(param, long))?TRUE:FALSE;
break;
#ifdef USE_LIBSSH2
@@ -2309,14 +2323,14 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
/*
* disable libcurl transfer encoding is used
*/
- data->set.http_te_skip = (bool)(0 == va_arg(param, long));
+ data->set.http_te_skip = (0 == va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_HTTP_CONTENT_DECODING:
/*
* raw data passed to the application when content encoding is used
*/
- data->set.http_ce_skip = (bool)(0 == va_arg(param, long));
+ data->set.http_ce_skip = (0 == va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_NEW_FILE_PERMS:
@@ -2478,7 +2492,7 @@ CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option,
break;
case CURLOPT_WILDCARDMATCH:
- data->set.wildcardmatch = (bool)(0 != va_arg(param, long));
+ data->set.wildcardmatch = (0 != va_arg(param, long))?TRUE:FALSE;
break;
case CURLOPT_CHUNK_BGN_FUNCTION:
data->set.chunk_bgn = va_arg(param, curl_chunk_bgn_callback);
@@ -2543,6 +2557,10 @@ static void conn_free(struct connectdata *conn)
if(CURL_SOCKET_BAD != conn->sock[FIRSTSOCKET])
Curl_closesocket(conn, conn->sock[FIRSTSOCKET]);
+#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+ Curl_ntlm_wb_cleanup(conn);
+#endif
+
Curl_safefree(conn->user);
Curl_safefree(conn->passwd);
Curl_safefree(conn->proxyuser);
@@ -2567,6 +2585,11 @@ static void conn_free(struct connectdata *conn)
Curl_llist_destroy(conn->pend_pipe, NULL);
Curl_llist_destroy(conn->done_pipe, NULL);
+ conn->send_pipe = NULL;
+ conn->recv_pipe = NULL;
+ conn->pend_pipe = NULL;
+ conn->done_pipe = NULL;
+
Curl_safefree(conn->localdev);
Curl_free_ssl_config(&conn->ssl_config);
@@ -2621,7 +2644,7 @@ CURLcode Curl_disconnect(struct connectdata *conn, bool dead_connection)
if(has_host_ntlm || has_proxy_ntlm) {
data->state.authproblem = FALSE;
- Curl_ntlm_cleanup(conn);
+ Curl_http_ntlm_cleanup(conn);
}
}
@@ -2773,11 +2796,11 @@ static struct SessionHandle* gethandleathead(struct curl_llist *pipeline)
void Curl_getoff_all_pipelines(struct SessionHandle *data,
struct connectdata *conn)
{
- bool recv_head = (bool)(conn->readchannel_inuse &&
- (gethandleathead(conn->recv_pipe) == data));
+ bool recv_head = (conn->readchannel_inuse &&
+ (gethandleathead(conn->recv_pipe) == data)) ? TRUE : FALSE;
- bool send_head = (bool)(conn->writechannel_inuse &&
- (gethandleathead(conn->send_pipe) == data));
+ bool send_head = (conn->writechannel_inuse &&
+ (gethandleathead(conn->send_pipe) == data)) ? TRUE : FALSE;
if(Curl_removeHandleFromPipeline(data, conn->recv_pipe) && recv_head)
conn->readchannel_inuse = FALSE;
@@ -3002,7 +3025,8 @@ ConnectionExists(struct SessionHandle *data,
}
if((needle->handler->protocol & CURLPROTO_FTP) ||
((needle->handler->protocol & CURLPROTO_HTTP) &&
- (data->state.authhost.want==CURLAUTH_NTLM))) {
+ ((data->state.authhost.want==CURLAUTH_NTLM) ||
+ (data->state.authhost.want==CURLAUTH_NTLM_WB)))) {
/* This is FTP or HTTP+NTLM, verify that we're using the same name
and password as well */
if(!strequal(needle->user, check->user) ||
@@ -3203,8 +3227,13 @@ static CURLcode ConnectPlease(struct SessionHandle *data,
/* All is cool, we store the current information */
conn->ip_addr = addr;
- if(*connected)
+ if(*connected) {
result = Curl_connected_proxy(conn);
+ if(!result) {
+ conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
+ Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
+ }
+ }
}
if(result)
@@ -3297,7 +3326,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
*protocol_done = FALSE;
- if(conn->bits.tcpconnect && conn->bits.protoconnstart) {
+ if(conn->bits.tcpconnect[FIRSTSOCKET] && conn->bits.protoconnstart) {
/* We already are connected, get back. This may happen when the connect
worked fine in the first call, like when we connect to a local server
or proxy. Note that we don't know if the protocol is actually done.
@@ -3310,7 +3339,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
return CURLE_OK;
}
- if(!conn->bits.tcpconnect) {
+ if(!conn->bits.tcpconnect[FIRSTSOCKET]) {
Curl_pgrsTime(data, TIMER_CONNECT); /* connect done */
Curl_verboseconnect(conn);
@@ -3504,18 +3533,20 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
#else /* CURL_DISABLE_PROXY */
- conn->bits.proxy = (bool)(data->set.str[STRING_PROXY] &&
- *data->set.str[STRING_PROXY]);
- conn->bits.httpproxy = (bool)(conn->bits.proxy &&
- (conn->proxytype == CURLPROXY_HTTP ||
- conn->proxytype == CURLPROXY_HTTP_1_0));
+ /* note that these two proxy bits are now just on what looks to be
+ requested, they may be altered down the road */
+ conn->bits.proxy = (data->set.str[STRING_PROXY] &&
+ *data->set.str[STRING_PROXY])?TRUE:FALSE;
+ conn->bits.httpproxy = (conn->bits.proxy &&
+ (conn->proxytype == CURLPROXY_HTTP ||
+ conn->proxytype == CURLPROXY_HTTP_1_0))?TRUE:FALSE;
conn->bits.proxy_user_passwd =
- (bool)(NULL != data->set.str[STRING_PROXYUSERNAME]);
+ (NULL != data->set.str[STRING_PROXYUSERNAME])?TRUE:FALSE;
conn->bits.tunnel_proxy = data->set.tunnel_thru_httpproxy;
#endif /* CURL_DISABLE_PROXY */
- conn->bits.user_passwd = (bool)(NULL != data->set.str[STRING_USERNAME]);
+ conn->bits.user_passwd = (NULL != data->set.str[STRING_USERNAME])?TRUE:FALSE;
conn->bits.ftp_use_epsv = data->set.ftp_use_epsv;
conn->bits.ftp_use_eprt = data->set.ftp_use_eprt;
@@ -3524,6 +3555,13 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
conn->ip_version = data->set.ipver;
+#if defined(USE_NTLM) && defined(NTLM_WB_ENABLED)
+ conn->ntlm_auth_hlpr_socket = CURL_SOCKET_BAD;
+ conn->ntlm_auth_hlpr_pid = 0;
+ conn->challenge_header = NULL;
+ conn->response_header = NULL;
+#endif
+
if(data->multi && Curl_multi_canPipeline(data->multi) &&
!conn->master_buffer) {
/* Allocate master_buffer to be used for pipelining */
@@ -3566,6 +3604,12 @@ static struct connectdata *allocate_conn(struct SessionHandle *data)
Curl_llist_destroy(conn->recv_pipe, NULL);
Curl_llist_destroy(conn->pend_pipe, NULL);
Curl_llist_destroy(conn->done_pipe, NULL);
+
+ conn->send_pipe = NULL;
+ conn->recv_pipe = NULL;
+ conn->pend_pipe = NULL;
+ conn->done_pipe = NULL;
+
Curl_safefree(conn->master_buffer);
Curl_safefree(conn->localdev);
Curl_safefree(conn);
@@ -3852,7 +3896,7 @@ static CURLcode setup_range(struct SessionHandle *data)
else
s->range = strdup(data->set.str[STRING_SET_RANGE]);
- s->rangestringalloc = (bool)(s->range?TRUE:FALSE);
+ s->rangestringalloc = (s->range)?TRUE:FALSE;
if(!s->range)
return CURLE_OUT_OF_MEMORY;
@@ -4392,8 +4436,10 @@ static CURLcode parse_remote_port(struct SessionHandle *data,
if(!url)
return CURLE_OUT_OF_MEMORY;
- if(data->change.url_alloc)
- free(data->change.url);
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
data->change.url = url;
data->change.url_alloc = TRUE;
@@ -4617,11 +4663,12 @@ static void reuse_conn(struct connectdata *old_conn,
/* host can change, when doing keepalive with a proxy ! */
if(conn->bits.proxy) {
- free(conn->host.rawalloc);
+ Curl_safefree(conn->host.rawalloc);
conn->host=old_conn->host;
}
else
- free(old_conn->host.rawalloc); /* free the newly allocated name buffer */
+ /* free the newly allocated name buffer */
+ Curl_safefree(old_conn->host.rawalloc);
/* persist connection info in session handle */
Curl_persistconninfo(conn);
@@ -4633,10 +4680,17 @@ static void reuse_conn(struct connectdata *old_conn,
Curl_safefree(old_conn->passwd);
Curl_safefree(old_conn->proxyuser);
Curl_safefree(old_conn->proxypasswd);
+
Curl_llist_destroy(old_conn->send_pipe, NULL);
Curl_llist_destroy(old_conn->recv_pipe, NULL);
Curl_llist_destroy(old_conn->pend_pipe, NULL);
Curl_llist_destroy(old_conn->done_pipe, NULL);
+
+ old_conn->send_pipe = NULL;
+ old_conn->recv_pipe = NULL;
+ old_conn->pend_pipe = NULL;
+ old_conn->done_pipe = NULL;
+
Curl_safefree(old_conn->master_buffer);
}
@@ -4713,14 +4767,19 @@ static CURLcode create_conn(struct SessionHandle *data,
*/
Curl_safefree(data->state.pathbuffer);
+ data->state.path = NULL;
+
data->state.pathbuffer = malloc(urllen+2);
if(NULL == data->state.pathbuffer)
return CURLE_OUT_OF_MEMORY; /* really bad error */
data->state.path = data->state.pathbuffer;
conn->host.rawalloc = malloc(urllen+2);
- if(NULL == conn->host.rawalloc)
+ if(NULL == conn->host.rawalloc) {
+ Curl_safefree(data->state.pathbuffer);
+ data->state.path = NULL;
return CURLE_OUT_OF_MEMORY;
+ }
conn->host.name = conn->host.rawalloc;
conn->host.name[0] = 0;
@@ -4745,6 +4804,11 @@ static CURLcode create_conn(struct SessionHandle *data,
return CURLE_OUT_OF_MEMORY;
}
+ if(data->change.url_alloc) {
+ Curl_safefree(data->change.url);
+ data->change.url_alloc = FALSE;
+ }
+
data->change.url = reurl;
data->change.url_alloc = TRUE; /* free this later */
}
@@ -4821,6 +4885,8 @@ static CURLcode create_conn(struct SessionHandle *data,
conn->bits.httpproxy = TRUE;
#endif
}
+ else
+ conn->bits.httpproxy = FALSE; /* not a HTTP proxy */
conn->bits.proxy = TRUE;
}
else {
@@ -4862,7 +4928,7 @@ static CURLcode create_conn(struct SessionHandle *data,
/* Setup a "faked" transfer that'll do nothing */
if(CURLE_OK == result) {
conn->data = data;
- conn->bits.tcpconnect = TRUE; /* we are "connected */
+ conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */
ConnectionStore(data, conn);
@@ -4970,6 +5036,9 @@ static CURLcode create_conn(struct SessionHandle *data,
ConnectionStore(data, conn);
}
+ /* Setup and init stuff before DO starts, in preparing for the transfer. */
+ do_init(conn);
+
/*
* Setup whatever necessary for a resumed transfer
*/
@@ -5007,7 +5076,7 @@ static CURLcode create_conn(struct SessionHandle *data,
CURLcode Curl_setup_conn(struct connectdata *conn,
bool *protocol_done)
{
- CURLcode result=CURLE_OK;
+ CURLcode result = CURLE_OK;
struct SessionHandle *data = conn->data;
Curl_pgrsTime(data, TIMER_NAMELOOKUP);
@@ -5053,13 +5122,19 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
result = ConnectPlease(data, conn, &connected);
+ if(result && !conn->ip_addr) {
+ /* transport connection failure not related with authentication */
+ conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
+ return result;
+ }
+
if(connected) {
result = Curl_protocol_connect(conn, protocol_done);
if(CURLE_OK == result)
- conn->bits.tcpconnect = TRUE;
+ conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
}
else
- conn->bits.tcpconnect = FALSE;
+ conn->bits.tcpconnect[FIRSTSOCKET] = FALSE;
/* if the connection was closed by the server while exchanging
authentication informations, retry with the new set
@@ -5078,7 +5153,7 @@ CURLcode Curl_setup_conn(struct connectdata *conn,
else {
Curl_pgrsTime(data, TIMER_CONNECT); /* we're connected already */
Curl_pgrsTime(data, TIMER_APPCONNECT); /* we're connected already */
- conn->bits.tcpconnect = TRUE;
+ conn->bits.tcpconnect[FIRSTSOCKET] = TRUE;
*protocol_done = TRUE;
Curl_verboseconnect(conn);
Curl_updateconninfo(conn, conn->sock[FIRSTSOCKET]);
@@ -5316,9 +5391,6 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
struct connectdata *conn = *connp;
struct SessionHandle *data = conn->data;
- /* setup and init stuff before DO starts, in preparing for the transfer */
- do_init(conn);
-
if(conn->handler->do_it) {
/* generic protocol-specific function pointer set in curl_connect() */
result = conn->handler->do_it(conn, done);