diff options
Diffstat (limited to 'lib/url.c')
-rw-r--r-- | lib/url.c | 302 |
1 files changed, 187 insertions, 115 deletions
@@ -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); |