diff options
author | Brad King <brad.king@kitware.com> | 2020-06-26 13:30:18 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2020-06-26 13:30:25 (GMT) |
commit | 42d9b3dc6af8a70f1238fce5f5db2e5910452f0b (patch) | |
tree | 8701572d53316e111fec262c78450ecc22e8762d /Utilities/cmcurl/lib/url.c | |
parent | 1f47a65c7ac1b09f013543d2bd2ca38d2502f3a1 (diff) | |
parent | e5ff413f41877dc46498c384fa4f6e5b23ec1476 (diff) | |
download | CMake-42d9b3dc6af8a70f1238fce5f5db2e5910452f0b.zip CMake-42d9b3dc6af8a70f1238fce5f5db2e5910452f0b.tar.gz CMake-42d9b3dc6af8a70f1238fce5f5db2e5910452f0b.tar.bz2 |
Merge topic 'update-curl' into release-3.18
e5ff413f41 curl: Set build options the way we need for CMake
0ef8fa5000 Merge branch 'upstream-curl' into update-curl
5717fdc114 curl 2020-06-23 (e9db32a0)
39f7cfad31 curl: Update script to get curl 7.71.0
Acked-by: Kitware Robot <kwrobot@kitware.com>
Merge-request: !4937
Diffstat (limited to 'Utilities/cmcurl/lib/url.c')
-rw-r--r-- | Utilities/cmcurl/lib/url.c | 442 |
1 files changed, 247 insertions, 195 deletions
diff --git a/Utilities/cmcurl/lib/url.c b/Utilities/cmcurl/lib/url.c index 47fc66a..8225e61 100644 --- a/Utilities/cmcurl/lib/url.c +++ b/Utilities/cmcurl/lib/url.c @@ -114,6 +114,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "http_ntlm.h" #include "curl_rtmp.h" #include "gopher.h" +#include "mqtt.h" #include "http_proxy.h" #include "conncache.h" #include "multihandle.h" @@ -121,6 +122,7 @@ bool curl_win32_idn_to_ascii(const char *in, char **out); #include "strdup.h" #include "setopt.h" #include "altsvc.h" +#include "dynbuf.h" /* The last 3 #include files should be in this order */ #include "curl_printf.h" @@ -140,19 +142,21 @@ static unsigned int get_protocol_family(unsigned int protocol); /* - * Protocol table. + * Protocol table. Schemes (roughly) in 2019 popularity order: + * + * HTTPS, HTTP, FTP, FTPS, SFTP, FILE, SCP, SMTP, LDAP, IMAPS, TELNET, IMAP, + * LDAPS, SMTPS, TFTP, SMB, POP3, GOPHER POP3S, RTSP, RTMP, SMBS, DICT */ - static const struct Curl_handler * const protocols[] = { -#ifndef CURL_DISABLE_HTTP - &Curl_handler_http, -#endif - #if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP) &Curl_handler_https, #endif +#ifndef CURL_DISABLE_HTTP + &Curl_handler_http, +#endif + #ifndef CURL_DISABLE_FTP &Curl_handler_ftp, #endif @@ -161,12 +165,23 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_ftps, #endif -#ifndef CURL_DISABLE_TELNET - &Curl_handler_telnet, +#if defined(USE_SSH) + &Curl_handler_sftp, #endif -#ifndef CURL_DISABLE_DICT - &Curl_handler_dict, +#ifndef CURL_DISABLE_FILE + &Curl_handler_file, +#endif + +#if defined(USE_SSH) && !defined(USE_WOLFSSH) + &Curl_handler_scp, +#endif + +#ifndef CURL_DISABLE_SMTP + &Curl_handler_smtp, +#ifdef USE_SSL + &Curl_handler_smtps, +#endif #endif #ifndef CURL_DISABLE_LDAP @@ -178,22 +193,6 @@ static const struct Curl_handler * const protocols[] = { #endif #endif -#ifndef CURL_DISABLE_FILE - &Curl_handler_file, -#endif - -#ifndef CURL_DISABLE_TFTP - &Curl_handler_tftp, -#endif - -#if defined(USE_SSH) && !defined(USE_WOLFSSH) - &Curl_handler_scp, -#endif - -#if defined(USE_SSH) - &Curl_handler_sftp, -#endif - #ifndef CURL_DISABLE_IMAP &Curl_handler_imap, #ifdef USE_SSL @@ -201,6 +200,14 @@ static const struct Curl_handler * const protocols[] = { #endif #endif +#ifndef CURL_DISABLE_TELNET + &Curl_handler_telnet, +#endif + +#ifndef CURL_DISABLE_TFTP + &Curl_handler_tftp, +#endif + #ifndef CURL_DISABLE_POP3 &Curl_handler_pop3, #ifdef USE_SSL @@ -217,17 +224,14 @@ static const struct Curl_handler * const protocols[] = { #endif #endif -#ifndef CURL_DISABLE_SMTP - &Curl_handler_smtp, -#ifdef USE_SSL - &Curl_handler_smtps, -#endif -#endif - #ifndef CURL_DISABLE_RTSP &Curl_handler_rtsp, #endif +#ifdef CURL_ENABLE_MQTT + &Curl_handler_mqtt, +#endif + #ifndef CURL_DISABLE_GOPHER &Curl_handler_gopher, #endif @@ -241,6 +245,10 @@ static const struct Curl_handler * const protocols[] = { &Curl_handler_rtmpts, #endif +#ifndef CURL_DISABLE_DICT + &Curl_handler_dict, +#endif + (struct Curl_handler *) NULL }; @@ -273,10 +281,16 @@ void Curl_freeset(struct Curl_easy *data) { /* Free all dynamic strings stored in the data->set substructure. */ enum dupstring i; + enum dupblob j; + for(i = (enum dupstring)0; i < STRING_LAST; i++) { Curl_safefree(data->set.str[i]); } + for(j = (enum dupblob)0; j < BLOB_LAST; j++) { + Curl_safefree(data->set.blobs[j]); + } + if(data->change.referer_alloc) { Curl_safefree(data->change.referer); data->change.referer_alloc = FALSE; @@ -375,7 +389,7 @@ CURLcode Curl_close(struct Curl_easy **datap) up_free(data); Curl_safefree(data->state.buffer); - Curl_safefree(data->state.headerbuff); + Curl_dyn_free(&data->state.headerb); Curl_safefree(data->state.ulbuf); Curl_flush_cookies(data, TRUE); #ifdef USE_ALTSVC @@ -402,9 +416,20 @@ CURLcode Curl_close(struct Curl_easy **datap) Curl_share_unlock(data, CURL_LOCK_DATA_SHARE); } + Curl_safefree(data->state.aptr.proxyuserpwd); + Curl_safefree(data->state.aptr.uagent); + Curl_safefree(data->state.aptr.userpwd); + Curl_safefree(data->state.aptr.accept_encoding); + Curl_safefree(data->state.aptr.te); + Curl_safefree(data->state.aptr.rangeline); + Curl_safefree(data->state.aptr.ref); + Curl_safefree(data->state.aptr.host); + Curl_safefree(data->state.aptr.cookiehost); + Curl_safefree(data->state.aptr.rtsp_transport); + #ifndef CURL_DISABLE_DOH - free(data->req.doh.probe[0].serverdoh.memory); - free(data->req.doh.probe[1].serverdoh.memory); + Curl_dyn_free(&data->req.doh.probe[0].serverdoh); + Curl_dyn_free(&data->req.doh.probe[1].serverdoh); curl_slist_free_all(data->req.doh.headers); #endif @@ -448,7 +473,7 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) set->postfieldsize = -1; /* unknown size */ set->maxredirs = -1; /* allow any amount by default */ - set->httpreq = HTTPREQ_GET; /* Default HTTP request */ + set->method = HTTPREQ_GET; /* Default HTTP request */ set->rtspreq = RTSPREQ_OPTIONS; /* Default RTSP request */ #ifndef CURL_DISABLE_FTP set->ftp_use_epsv = TRUE; /* FTP defaults to EPSV operations */ @@ -487,7 +512,9 @@ CURLcode Curl_init_userdefined(struct Curl_easy *data) type */ set->ssl.primary.sessionid = TRUE; /* session ID caching enabled by default */ +#ifndef CURL_DISABLE_PROXY set->proxy_ssl = set->ssl; +#endif set->new_file_perms = 0644; /* Default permissions */ set->new_directory_perms = 0755; /* Default permissions */ @@ -596,38 +623,22 @@ CURLcode Curl_open(struct Curl_easy **curl) return result; } - /* We do some initial setup here, all those fields that can't be just 0 */ - - data->state.buffer = malloc(READBUFFER_SIZE + 1); - if(!data->state.buffer) { - DEBUGF(fprintf(stderr, "Error: malloc of buffer failed\n")); - result = CURLE_OUT_OF_MEMORY; - } - else { - data->state.headerbuff = malloc(HEADERSIZE); - if(!data->state.headerbuff) { - DEBUGF(fprintf(stderr, "Error: malloc of headerbuff failed\n")); - result = CURLE_OUT_OF_MEMORY; - } - else { - result = Curl_init_userdefined(data); - - data->state.headersize = HEADERSIZE; - Curl_convert_init(data); - Curl_initinfo(data); + result = Curl_init_userdefined(data); + if(!result) { + Curl_dyn_init(&data->state.headerb, CURL_MAX_HTTP_HEADER); + Curl_convert_init(data); + Curl_initinfo(data); - /* most recent connection is not yet defined */ - data->state.lastconnect = NULL; + /* most recent connection is not yet defined */ + data->state.lastconnect = NULL; - data->progress.flags |= PGRS_HIDE; - data->state.current_speed = -1; /* init to negative == impossible */ - } + data->progress.flags |= PGRS_HIDE; + data->state.current_speed = -1; /* init to negative == impossible */ } if(result) { Curl_resolver_cleanup(data->state.resolver); - free(data->state.buffer); - free(data->state.headerbuff); + Curl_dyn_free(&data->state.headerb); Curl_freeset(data); free(data); data = NULL; @@ -679,9 +690,7 @@ static void conn_reset_all_postponed_data(struct connectdata *conn) static void conn_shutdown(struct connectdata *conn) { - if(!conn) - return; - + DEBUGASSERT(conn); infof(conn->data, "Closing connection %ld\n", conn->connection_id); DEBUGASSERT(conn->data); @@ -702,54 +711,40 @@ static void conn_shutdown(struct connectdata *conn) Curl_closesocket(conn, conn->tempsock[0]); if(CURL_SOCKET_BAD != conn->tempsock[1]) Curl_closesocket(conn, conn->tempsock[1]); - - /* unlink ourselves. this should be called last since other shutdown - procedures need a valid conn->data and this may clear it. */ - Curl_conncache_remove_conn(conn->data, conn, TRUE); } static void conn_free(struct connectdata *conn) { - if(!conn) - return; + DEBUGASSERT(conn); Curl_free_idnconverted_hostname(&conn->host); Curl_free_idnconverted_hostname(&conn->conn_to_host); +#ifndef CURL_DISABLE_PROXY Curl_free_idnconverted_hostname(&conn->http_proxy.host); Curl_free_idnconverted_hostname(&conn->socks_proxy.host); - - Curl_safefree(conn->user); - Curl_safefree(conn->passwd); - Curl_safefree(conn->sasl_authzid); - Curl_safefree(conn->options); Curl_safefree(conn->http_proxy.user); Curl_safefree(conn->socks_proxy.user); Curl_safefree(conn->http_proxy.passwd); Curl_safefree(conn->socks_proxy.passwd); - Curl_safefree(conn->allocptr.proxyuserpwd); - Curl_safefree(conn->allocptr.uagent); - Curl_safefree(conn->allocptr.userpwd); - Curl_safefree(conn->allocptr.accept_encoding); - Curl_safefree(conn->allocptr.te); - Curl_safefree(conn->allocptr.rangeline); - Curl_safefree(conn->allocptr.ref); - Curl_safefree(conn->allocptr.host); - Curl_safefree(conn->allocptr.cookiehost); - Curl_safefree(conn->allocptr.rtsp_transport); - Curl_safefree(conn->trailer); + Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */ + Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */ + Curl_free_primary_ssl_config(&conn->proxy_ssl_config); +#endif + Curl_safefree(conn->user); + Curl_safefree(conn->passwd); + Curl_safefree(conn->sasl_authzid); + Curl_safefree(conn->options); + Curl_dyn_free(&conn->trailer); Curl_safefree(conn->host.rawalloc); /* host name buffer */ Curl_safefree(conn->conn_to_host.rawalloc); /* host name buffer */ Curl_safefree(conn->hostname_resolve); Curl_safefree(conn->secondaryhostname); - Curl_safefree(conn->http_proxy.host.rawalloc); /* http proxy name buffer */ - Curl_safefree(conn->socks_proxy.host.rawalloc); /* socks proxy name buffer */ Curl_safefree(conn->connect_state); conn_reset_all_postponed_data(conn); Curl_llist_destroy(&conn->easyq, NULL); Curl_safefree(conn->localdev); Curl_free_primary_ssl_config(&conn->ssl_config); - Curl_free_primary_ssl_config(&conn->proxy_ssl_config); #ifdef USE_UNIX_SOCKETS Curl_safefree(conn->unix_domain_socket); @@ -778,13 +773,17 @@ static void conn_free(struct connectdata *conn) CURLcode Curl_disconnect(struct Curl_easy *data, struct connectdata *conn, bool dead_connection) { - if(!conn) - return CURLE_OK; /* this is closed and fine already */ + /* there must be a connection to close */ + DEBUGASSERT(conn); - if(!data) { - DEBUGF(infof(data, "DISCONNECT without easy handle, ignoring\n")); - return CURLE_OK; - } + /* it must be removed from the connection cache */ + DEBUGASSERT(!conn->bundle); + + /* there must be an associated transfer */ + DEBUGASSERT(data); + + /* the transfer must be detached from the connection */ + DEBUGASSERT(!data->conn); /* * If this connection isn't marked to force-close, leave it open if there @@ -800,16 +799,11 @@ CURLcode Curl_disconnect(struct Curl_easy *data, conn->dns_entry = NULL; } - Curl_hostcache_prune(data); /* kill old DNS cache entries */ - -#if !defined(CURL_DISABLE_HTTP) && defined(USE_NTLM) /* Cleanup NTLM connection-related data */ Curl_http_auth_cleanup_ntlm(conn); -#endif -#if !defined(CURL_DISABLE_HTTP) && defined(USE_SPNEGO) + /* Cleanup NEGOTIATE connection-related data */ Curl_http_auth_cleanup_negotiate(conn); -#endif /* the protocol specific disconnect handler and conn_shutdown need a transfer for the connection! */ @@ -871,8 +865,8 @@ static int IsMultiplexingPossible(const struct Curl_easy *handle, #ifndef CURL_DISABLE_PROXY static bool -proxy_info_matches(const struct proxy_info* data, - const struct proxy_info* needle) +proxy_info_matches(const struct proxy_info *data, + const struct proxy_info *needle) { if((data->proxytype == needle->proxytype) && (data->port == needle->port) && @@ -883,8 +877,8 @@ proxy_info_matches(const struct proxy_info* data, } static bool -socks_proxy_info_matches(const struct proxy_info* data, - const struct proxy_info* needle) +socks_proxy_info_matches(const struct proxy_info *data, + const struct proxy_info *needle) { if(!proxy_info_matches(data, needle)) return FALSE; @@ -1006,8 +1000,12 @@ static int call_extract_if_dead(struct connectdata *conn, void *param) static void prune_dead_connections(struct Curl_easy *data) { struct curltime now = Curl_now(); - timediff_t elapsed = + timediff_t elapsed; + + CONNCACHE_LOCK(data); + elapsed = Curl_timediff(now, data->state.conn_cache->last_cleanup); + CONNCACHE_UNLOCK(data); if(elapsed >= 1000L) { struct prunedead prune; @@ -1015,10 +1013,17 @@ static void prune_dead_connections(struct Curl_easy *data) prune.extracted = NULL; while(Curl_conncache_foreach(data, data->state.conn_cache, &prune, call_extract_if_dead)) { + /* unlocked */ + + /* remove connection from cache */ + Curl_conncache_remove_conn(data, prune.extracted, TRUE); + /* disconnect it */ (void)Curl_disconnect(data, prune.extracted, /* dead_connection */TRUE); } + CONNCACHE_LOCK(data); data->state.conn_cache->last_cleanup = now; + CONNCACHE_UNLOCK(data); } } @@ -1051,10 +1056,14 @@ ConnectionExists(struct Curl_easy *data, bool wantNTLMhttp = ((data->state.authhost.want & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && (needle->handler->protocol & PROTO_FAMILY_HTTP)); +#ifndef CURL_DISABLE_PROXY bool wantProxyNTLMhttp = (needle->bits.proxy_user_passwd && ((data->state.authproxy.want & (CURLAUTH_NTLM | CURLAUTH_NTLM_WB)) && (needle->handler->protocol & PROTO_FAMILY_HTTP))); +#else + bool wantProxyNTLMhttp = FALSE; +#endif #endif *force_reuse = FALSE; @@ -1078,7 +1087,7 @@ ConnectionExists(struct Curl_easy *data, if(data->set.pipewait) { infof(data, "Server doesn't support multiplex yet, wait\n"); *waitpipe = TRUE; - Curl_conncache_unlock(data); + CONNCACHE_UNLOCK(data); return FALSE; /* no re-use */ } @@ -1151,7 +1160,8 @@ ConnectionExists(struct Curl_easy *data, continue; if(strcmp(needle->unix_domain_socket, check->unix_domain_socket)) continue; - if(needle->abstract_unix_socket != check->abstract_unix_socket) + if(needle->bits.abstract_unix_socket != + check->bits.abstract_unix_socket) continue; } else if(check->unix_domain_socket) @@ -1162,10 +1172,11 @@ ConnectionExists(struct Curl_easy *data, (check->handler->flags&PROTOPT_SSL)) /* don't do mixed SSL and non-SSL connections */ if(get_protocol_family(check->handler->protocol) != - needle->handler->protocol || !check->tls_upgraded) + needle->handler->protocol || !check->bits.tls_upgraded) /* except protocols that have been upgraded via TLS */ continue; +#ifndef CURL_DISABLE_PROXY if(needle->bits.httpproxy != check->bits.httpproxy || needle->bits.socksproxy != check->bits.socksproxy) continue; @@ -1174,7 +1185,7 @@ ConnectionExists(struct Curl_easy *data, !socks_proxy_info_matches(&needle->socks_proxy, &check->socks_proxy)) continue; - +#endif if(needle->bits.conn_to_host != check->bits.conn_to_host) /* don't mix connections that use the "connect to host" feature and * connections that don't use this feature */ @@ -1185,6 +1196,7 @@ ConnectionExists(struct Curl_easy *data, * connections that don't use this feature */ continue; +#ifndef CURL_DISABLE_PROXY if(needle->bits.httpproxy) { if(!proxy_info_matches(&needle->http_proxy, &check->http_proxy)) continue; @@ -1211,6 +1223,7 @@ ConnectionExists(struct Curl_easy *data, } } } +#endif DEBUGASSERT(!check->data || GOOD_EASY_HANDLE(check->data)); @@ -1253,15 +1266,18 @@ ConnectionExists(struct Curl_easy *data, } } - if(!needle->bits.httpproxy || (needle->handler->flags&PROTOPT_SSL) || - needle->bits.tunnel_proxy) { + if((needle->handler->flags&PROTOPT_SSL) +#ifndef CURL_DISABLE_PROXY + || !needle->bits.httpproxy || needle->bits.tunnel_proxy +#endif + ) { /* The requested connection does not use a HTTP proxy or it uses SSL or it is a non-SSL protocol tunneled or it is a non-SSL protocol which is allowed to be upgraded via TLS */ if((strcasecompare(needle->handler->scheme, check->handler->scheme) || (get_protocol_family(check->handler->protocol) == - needle->handler->protocol && check->tls_upgraded)) && + needle->handler->protocol && check->bits.tls_upgraded)) && (!needle->bits.conn_to_host || strcasecompare( needle->conn_to_host.name, check->conn_to_host.name)) && (!needle->bits.conn_to_port || @@ -1323,6 +1339,7 @@ ConnectionExists(struct Curl_easy *data, continue; } +#ifndef CURL_DISABLE_PROXY /* Same for Proxy NTLM authentication */ if(wantProxyNTLMhttp) { /* Both check->http_proxy.user and check->http_proxy.passwd can be @@ -1338,7 +1355,7 @@ ConnectionExists(struct Curl_easy *data, /* Proxy connection is using NTLM auth but we don't want NTLM */ continue; } - +#endif if(wantNTLMhttp || wantProxyNTLMhttp) { /* Credentials are already checked, we can use this connection */ chosen = check; @@ -1402,11 +1419,12 @@ ConnectionExists(struct Curl_easy *data, if(chosen) { /* mark it as used before releasing the lock */ chosen->data = data; /* own it! */ - Curl_conncache_unlock(data); + Curl_attach_connnection(data, chosen); + CONNCACHE_UNLOCK(data); *usethis = chosen; return TRUE; /* yes, we found one to use! */ } - Curl_conncache_unlock(data); + CONNCACHE_UNLOCK(data); if(foundPendingCandidate && data->set.pipewait) { infof(data, @@ -1425,8 +1443,10 @@ void Curl_verboseconnect(struct connectdata *conn) { if(conn->data->set.verbose) infof(conn->data, "Connected to %s (%s) port %ld (#%ld)\n", +#ifndef CURL_DISABLE_PROXY conn->bits.socksproxy ? conn->socks_proxy.host.dispname : conn->bits.httpproxy ? conn->http_proxy.host.dispname : +#endif conn->bits.conn_to_host ? conn->conn_to_host.dispname : conn->host.dispname, conn->ip_addr_str, conn->port, conn->connection_id); @@ -1573,8 +1593,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->ssl_extra = ssl; conn->ssl[0].backend = (void *)ssl; conn->ssl[1].backend = (void *)(ssl + sslsize); +#ifndef CURL_DISABLE_PROXY conn->proxy_ssl[0].backend = (void *)(ssl + 2 * sslsize); conn->proxy_ssl[1].backend = (void *)(ssl + 3 * sslsize); +#endif } #endif @@ -1613,10 +1635,10 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->data = data; /* Setup the association between this connection and the Curl_easy */ +#ifndef CURL_DISABLE_PROXY conn->http_proxy.proxytype = data->set.proxytype; conn->socks_proxy.proxytype = CURLPROXY_SOCKS4; -#if !defined(CURL_DISABLE_PROXY) /* 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] && @@ -1647,10 +1669,12 @@ static struct connectdata *allocate_conn(struct Curl_easy *data) conn->ssl_config.verifystatus = data->set.ssl.primary.verifystatus; conn->ssl_config.verifypeer = data->set.ssl.primary.verifypeer; conn->ssl_config.verifyhost = data->set.ssl.primary.verifyhost; +#ifndef CURL_DISABLE_PROXY conn->proxy_ssl_config.verifystatus = data->set.proxy_ssl.primary.verifystatus; conn->proxy_ssl_config.verifypeer = data->set.proxy_ssl.primary.verifypeer; conn->proxy_ssl_config.verifyhost = data->set.proxy_ssl.primary.verifyhost; +#endif conn->ip_version = data->set.ipver; conn->bits.connect_only = data->set.connect_only; conn->transport = TRNSPRT_TCP; /* most of them are TCP streams */ @@ -1996,7 +2020,7 @@ static CURLcode setup_range(struct Curl_easy *data) */ static CURLcode setup_connection_internals(struct connectdata *conn) { - const struct Curl_handler * p; + const struct Curl_handler *p; CURLcode result; /* Perform setup complement if some. */ @@ -2343,24 +2367,14 @@ static CURLcode parse_proxy(struct Curl_easy *data, static CURLcode parse_proxy_auth(struct Curl_easy *data, struct connectdata *conn) { - char proxyuser[MAX_CURL_USER_LENGTH]=""; - char proxypasswd[MAX_CURL_PASSWORD_LENGTH]=""; - CURLcode result; - - if(data->set.str[STRING_PROXYUSERNAME] != NULL) { - strncpy(proxyuser, data->set.str[STRING_PROXYUSERNAME], - MAX_CURL_USER_LENGTH); - proxyuser[MAX_CURL_USER_LENGTH-1] = '\0'; /*To be on safe side*/ - } - if(data->set.str[STRING_PROXYPASSWORD] != NULL) { - strncpy(proxypasswd, data->set.str[STRING_PROXYPASSWORD], - MAX_CURL_PASSWORD_LENGTH); - proxypasswd[MAX_CURL_PASSWORD_LENGTH-1] = '\0'; /*To be on safe side*/ - } + char *proxyuser = data->set.str[STRING_PROXYUSERNAME]; + char *proxypasswd = data->set.str[STRING_PROXYPASSWORD]; + CURLcode result = CURLE_OK; - result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL, - FALSE); - if(!result) + if(proxyuser) + result = Curl_urldecode(data, proxyuser, 0, &conn->http_proxy.user, NULL, + FALSE); + if(!result && proxypasswd) result = Curl_urldecode(data, proxypasswd, 0, &conn->http_proxy.passwd, NULL, FALSE); return result; @@ -2580,6 +2594,12 @@ CURLcode Curl_parse_login_details(const char *login, const size_t len, size_t plen; size_t olen; + /* the input length check is because this is called directcly from setopt + and isn't going through the regular string length check */ + size_t llen = strlen(login); + if(llen > CURL_MAX_INPUT_LENGTH) + return CURLE_BAD_FUNCTION_ARGUMENT; + /* Attempt to find the password separator */ if(passwdp) { psep = strchr(login, ':'); @@ -2776,12 +2796,14 @@ static CURLcode override_login(struct Curl_easy *data, /* for updated strings, we update them in the URL */ if(user_changed) { - uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, 0); + uc = curl_url_set(data->state.uh, CURLUPART_USER, *userp, + CURLU_URLENCODE); if(uc) return Curl_uc_to_curlcode(uc); } if(passwd_changed) { - uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, 0); + uc = curl_url_set(data->state.uh, CURLUPART_PASSWORD, *passwdp, + CURLU_URLENCODE); if(uc) return Curl_uc_to_curlcode(uc); } @@ -3040,7 +3062,14 @@ static CURLcode parse_connect_to_slist(struct Curl_easy *data, #ifdef USE_ALTSVC if(data->asi && !host && (port == -1) && - (conn->handler->protocol == CURLPROTO_HTTPS)) { + ((conn->handler->protocol == CURLPROTO_HTTPS) || +#ifdef CURLDEBUG + /* allow debug builds to circumvent the HTTPS restriction */ + getenv("CURL_ALTSVC_HTTP") +#else + 0 +#endif + )) { /* no connect_to match, try alt-svc! */ enum alpnid srcalpnid; bool hit; @@ -3147,7 +3176,7 @@ static CURLcode resolve_server(struct Curl_easy *data, else { bool longpath = FALSE; hostaddr->addr = Curl_unix2addr(path, &longpath, - conn->abstract_unix_socket); + conn->bits.abstract_unix_socket); if(hostaddr->addr) hostaddr->inuse++; else { @@ -3165,6 +3194,7 @@ static CURLcode resolve_server(struct Curl_easy *data, } else #endif + if(!conn->bits.proxy) { struct hostname *connhost; if(conn->bits.conn_to_host) @@ -3193,10 +3223,11 @@ static CURLcode resolve_server(struct Curl_easy *data, else if(!hostaddr) { failf(data, "Couldn't resolve host '%s'", connhost->dispname); - result = CURLE_COULDNT_RESOLVE_HOST; + result = CURLE_COULDNT_RESOLVE_HOST; /* don't return yet, we need to clean up the timeout first */ } } +#ifndef CURL_DISABLE_PROXY else { /* This is a proxy that hasn't been resolved yet. */ @@ -3222,6 +3253,7 @@ static CURLcode resolve_server(struct Curl_easy *data, /* don't return yet, we need to clean up the timeout first */ } } +#endif DEBUGASSERT(conn->dns_entry == NULL); conn->dns_entry = hostaddr; } @@ -3237,16 +3269,17 @@ static CURLcode resolve_server(struct Curl_easy *data, static void reuse_conn(struct connectdata *old_conn, struct connectdata *conn) { +#ifndef CURL_DISABLE_PROXY Curl_free_idnconverted_hostname(&old_conn->http_proxy.host); Curl_free_idnconverted_hostname(&old_conn->socks_proxy.host); free(old_conn->http_proxy.host.rawalloc); free(old_conn->socks_proxy.host.rawalloc); - + Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config); +#endif /* free the SSL config struct from this connection struct as this was allocated in vain and is targeted for destruction */ Curl_free_primary_ssl_config(&old_conn->ssl_config); - Curl_free_primary_ssl_config(&old_conn->proxy_ssl_config); conn->data = old_conn->data; @@ -3263,6 +3296,7 @@ static void reuse_conn(struct connectdata *old_conn, old_conn->passwd = NULL; } +#ifndef CURL_DISABLE_PROXY conn->bits.proxy_user_passwd = old_conn->bits.proxy_user_passwd; if(conn->bits.proxy_user_passwd) { /* use the new proxy user name and proxy password though */ @@ -3279,6 +3313,11 @@ static void reuse_conn(struct connectdata *old_conn, old_conn->http_proxy.passwd = NULL; old_conn->socks_proxy.passwd = NULL; } + Curl_safefree(old_conn->http_proxy.user); + Curl_safefree(old_conn->socks_proxy.user); + Curl_safefree(old_conn->http_proxy.passwd); + Curl_safefree(old_conn->socks_proxy.passwd); +#endif /* host can change, when doing keepalive with a proxy or if the case is different this time etc */ @@ -3306,10 +3345,6 @@ static void reuse_conn(struct connectdata *old_conn, Curl_safefree(old_conn->user); Curl_safefree(old_conn->passwd); Curl_safefree(old_conn->options); - Curl_safefree(old_conn->http_proxy.user); - Curl_safefree(old_conn->socks_proxy.user); - Curl_safefree(old_conn->http_proxy.passwd); - Curl_safefree(old_conn->socks_proxy.passwd); Curl_safefree(old_conn->localdev); Curl_llist_destroy(&old_conn->easyq, NULL); @@ -3394,7 +3429,7 @@ static CURLcode create_conn(struct Curl_easy *data, result = CURLE_OUT_OF_MEMORY; goto out; } - conn->abstract_unix_socket = data->set.abstract_unix_socket; + conn->bits.abstract_unix_socket = data->set.abstract_unix_socket; } #endif @@ -3404,7 +3439,6 @@ static CURLcode create_conn(struct Curl_easy *data, result = create_conn_helper_init_proxy(conn); if(result) goto out; -#endif /************************************************************* * If the protocol is using SSL and HTTP proxy is used, we set @@ -3412,6 +3446,7 @@ static CURLcode create_conn(struct Curl_easy *data, *************************************************************/ if((conn->given->flags&PROTOPT_SSL) && conn->bits.httpproxy) conn->bits.tunnel_proxy = TRUE; +#endif /************************************************************* * Figure out the remote port number and fix it in the URL @@ -3450,6 +3485,7 @@ static CURLcode create_conn(struct Curl_easy *data, if(result) goto out; } +#ifndef CURL_DISABLE_PROXY if(conn->bits.httpproxy) { result = Curl_idnconvert_hostname(conn, &conn->http_proxy.host); if(result) @@ -3460,6 +3496,7 @@ static CURLcode create_conn(struct Curl_easy *data, if(result) goto out; } +#endif /************************************************************* * Check whether the host and the "connect to host" are equal. @@ -3478,6 +3515,7 @@ static CURLcode create_conn(struct Curl_easy *data, conn->bits.conn_to_port = FALSE; } +#ifndef CURL_DISABLE_PROXY /************************************************************* * If the "connect to" feature is used with an HTTP proxy, * we set the tunnel_proxy bit. @@ -3485,6 +3523,7 @@ static CURLcode create_conn(struct Curl_easy *data, if((conn->bits.conn_to_host || conn->bits.conn_to_port) && conn->bits.httpproxy) conn->bits.tunnel_proxy = TRUE; +#endif /************************************************************* * Setup internals depending on protocol. Needs to be done after @@ -3517,6 +3556,7 @@ static CURLcode create_conn(struct Curl_easy *data, if(!result) { conn->bits.tcpconnect[FIRSTSOCKET] = TRUE; /* we are "connected */ + Curl_attach_connnection(data, conn); result = Curl_conncache_add_conn(data->state.conn_cache, conn); if(result) goto out; @@ -3531,7 +3571,6 @@ static CURLcode create_conn(struct Curl_easy *data, (void)conn->handler->done(conn, result, FALSE); goto out; } - Curl_attach_connnection(data, conn); Curl_setup_transfer(data, -1, -1, FALSE, -1); } @@ -3552,49 +3591,59 @@ static CURLcode create_conn(struct Curl_easy *data, copies will be separately allocated. */ data->set.ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_ORIG]; - data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; data->set.ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_ORIG]; - data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; data->set.ssl.primary.random_file = data->set.str[STRING_SSL_RANDOM_FILE]; - data->set.proxy_ssl.primary.random_file = - data->set.str[STRING_SSL_RANDOM_FILE]; data->set.ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; - data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; data->set.ssl.primary.cipher_list = data->set.str[STRING_SSL_CIPHER_LIST_ORIG]; - data->set.proxy_ssl.primary.cipher_list = - data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; data->set.ssl.primary.cipher_list13 = data->set.str[STRING_SSL_CIPHER13_LIST_ORIG]; - data->set.proxy_ssl.primary.cipher_list13 = - data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; data->set.ssl.primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_ORIG]; + +#ifndef CURL_DISABLE_PROXY + data->set.proxy_ssl.primary.CApath = data->set.str[STRING_SSL_CAPATH_PROXY]; + data->set.proxy_ssl.primary.CAfile = data->set.str[STRING_SSL_CAFILE_PROXY]; + data->set.proxy_ssl.primary.random_file = + data->set.str[STRING_SSL_RANDOM_FILE]; + data->set.proxy_ssl.primary.egdsocket = data->set.str[STRING_SSL_EGDSOCKET]; + data->set.proxy_ssl.primary.cipher_list = + data->set.str[STRING_SSL_CIPHER_LIST_PROXY]; + data->set.proxy_ssl.primary.cipher_list13 = + data->set.str[STRING_SSL_CIPHER13_LIST_PROXY]; data->set.proxy_ssl.primary.pinned_key = data->set.str[STRING_SSL_PINNEDPUBLICKEY_PROXY]; - - data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; data->set.proxy_ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_PROXY]; - data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; data->set.proxy_ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_PROXY]; - data->set.ssl.cert = data->set.str[STRING_CERT_ORIG]; data->set.proxy_ssl.cert = data->set.str[STRING_CERT_PROXY]; - data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; data->set.proxy_ssl.cert_type = data->set.str[STRING_CERT_TYPE_PROXY]; - data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; data->set.proxy_ssl.key = data->set.str[STRING_KEY_PROXY]; - data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; data->set.proxy_ssl.key_type = data->set.str[STRING_KEY_TYPE_PROXY]; - data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG]; data->set.proxy_ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_PROXY]; - data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG]; data->set.proxy_ssl.primary.clientcert = data->set.str[STRING_CERT_PROXY]; + data->set.proxy_ssl.cert_blob = data->set.blobs[BLOB_CERT_PROXY]; + data->set.proxy_ssl.key_blob = data->set.blobs[BLOB_KEY_PROXY]; +#endif + data->set.ssl.CRLfile = data->set.str[STRING_SSL_CRLFILE_ORIG]; + data->set.ssl.issuercert = data->set.str[STRING_SSL_ISSUERCERT_ORIG]; + data->set.ssl.cert = data->set.str[STRING_CERT_ORIG]; + data->set.ssl.cert_type = data->set.str[STRING_CERT_TYPE_ORIG]; + data->set.ssl.key = data->set.str[STRING_KEY_ORIG]; + data->set.ssl.key_type = data->set.str[STRING_KEY_TYPE_ORIG]; + data->set.ssl.key_passwd = data->set.str[STRING_KEY_PASSWD_ORIG]; + data->set.ssl.primary.clientcert = data->set.str[STRING_CERT_ORIG]; #ifdef USE_TLS_SRP data->set.ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_ORIG]; - data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; data->set.ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_ORIG]; +#ifndef CURL_DISABLE_PROXY + data->set.proxy_ssl.username = data->set.str[STRING_TLSAUTH_USERNAME_PROXY]; data->set.proxy_ssl.password = data->set.str[STRING_TLSAUTH_PASSWORD_PROXY]; #endif +#endif + + data->set.ssl.cert_blob = data->set.blobs[BLOB_CERT_ORIG]; + data->set.ssl.key_blob = data->set.blobs[BLOB_KEY_ORIG]; + data->set.ssl.issuercert_blob = data->set.blobs[BLOB_SSL_ISSUERCERT_ORIG]; if(!Curl_clone_primary_ssl_config(&data->set.ssl.primary, &conn->ssl_config)) { @@ -3602,11 +3651,13 @@ static CURLcode create_conn(struct Curl_easy *data, goto out; } +#ifndef CURL_DISABLE_PROXY if(!Curl_clone_primary_ssl_config(&data->set.proxy_ssl.primary, &conn->proxy_ssl_config)) { result = CURLE_OUT_OF_MEMORY; goto out; } +#endif prune_dead_connections(data); @@ -3644,12 +3695,17 @@ static CURLcode create_conn(struct Curl_easy *data, conn = conn_temp; *in_connect = conn; +#ifndef CURL_DISABLE_PROXY infof(data, "Re-using existing connection! (#%ld) with %s %s\n", conn->connection_id, conn->bits.proxy?"proxy":"host", conn->socks_proxy.host.name ? conn->socks_proxy.host.dispname : conn->http_proxy.host.name ? conn->http_proxy.host.dispname : - conn->host.dispname); + conn->host.dispname); +#else + infof(data, "Re-using existing connection! (#%ld) with host %s\n", + conn->connection_id, conn->host.dispname); +#endif } else { /* We have decided that we want a new connection. However, we may not @@ -3681,7 +3737,7 @@ static CURLcode create_conn(struct Curl_easy *data, /* The bundle is full. Extract the oldest connection. */ conn_candidate = Curl_conncache_extract_bundle(data, bundle); - Curl_conncache_unlock(data); + CONNCACHE_UNLOCK(data); if(conn_candidate) (void)Curl_disconnect(data, conn_candidate, @@ -3693,7 +3749,7 @@ static CURLcode create_conn(struct Curl_easy *data, } } else - Curl_conncache_unlock(data); + CONNCACHE_UNLOCK(data); } @@ -3727,6 +3783,8 @@ static CURLcode create_conn(struct Curl_easy *data, * This is a brand new connection, so let's store it in the connection * cache of ours! */ + Curl_attach_connnection(data, conn); + result = Curl_conncache_add_conn(data->state.conn_cache, conn); if(result) goto out; @@ -3778,10 +3836,12 @@ static CURLcode create_conn(struct Curl_easy *data, /* Strip trailing dots. resolve_server copied the name. */ strip_trailing_dot(&conn->host); +#ifndef CURL_DISABLE_PROXY if(conn->bits.httpproxy) strip_trailing_dot(&conn->http_proxy.host); if(conn->bits.socksproxy) strip_trailing_dot(&conn->socks_proxy.host); +#endif if(conn->bits.conn_to_host) strip_trailing_dot(&conn->conn_to_host); @@ -3812,22 +3872,23 @@ CURLcode Curl_setup_conn(struct connectdata *conn, } *protocol_done = FALSE; /* default to not done */ +#ifndef CURL_DISABLE_PROXY /* set proxy_connect_closed to false unconditionally already here since it is used strictly to provide extra information to a parent function in the case of proxy CONNECT failures and we must make sure we don't have it lingering set from a previous invoke */ conn->bits.proxy_connect_closed = FALSE; - +#endif /* * Set user-agent. Used for HTTP, but since we can attempt to tunnel * basically anything through a http proxy we can't limit this based on * protocol. */ if(data->set.str[STRING_USERAGENT]) { - Curl_safefree(conn->allocptr.uagent); - conn->allocptr.uagent = + Curl_safefree(data->state.aptr.uagent); + data->state.aptr.uagent = aprintf("User-Agent: %s\r\n", data->set.str[STRING_USERAGENT]); - if(!conn->allocptr.uagent) + if(!data->state.aptr.uagent) return CURLE_OUT_OF_MEMORY; } @@ -3881,7 +3942,7 @@ CURLcode Curl_connect(struct Curl_easy *data, result = create_conn(data, &conn, asyncp); if(!result) { - if(CONN_INUSE(conn)) + if(CONN_INUSE(conn) > 1) /* multiplexed */ *protocol_done = TRUE; else if(!*asyncp) { @@ -3898,11 +3959,10 @@ CURLcode Curl_connect(struct Curl_easy *data, else if(result && conn) { /* We're not allowed to return failure with memory left allocated in the connectdata struct, free those here */ + Curl_detach_connnection(data); + Curl_conncache_remove_conn(data, conn, TRUE); Curl_disconnect(data, conn, TRUE); } - else if(!result && !data->conn) - /* FILE: transfers already have the connection attached */ - Curl_attach_connnection(data, conn); return result; } @@ -3921,6 +3981,11 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) { struct SingleRequest *k = &data->req; + /* if this is a pushed stream, we need this: */ + CURLcode result = Curl_preconnect(data); + if(result) + return result; + if(conn) { conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */ @@ -3933,30 +3998,17 @@ CURLcode Curl_init_do(struct Curl_easy *data, struct connectdata *conn) data->state.done = FALSE; /* *_done() is not called yet */ data->state.expect100header = FALSE; - if(data->set.opt_no_body) /* in HTTP lingo, no body means using the HEAD request... */ - data->set.httpreq = HTTPREQ_HEAD; - else if(HTTPREQ_HEAD == data->set.httpreq) - /* ... but if unset there really is no perfect method that is the - "opposite" of HEAD but in reality most people probably think GET - then. The important thing is that we can't let it remain HEAD if the - opt_no_body is set FALSE since then we'll behave wrong when getting - HTTP. */ - data->set.httpreq = HTTPREQ_GET; + data->state.httpreq = HTTPREQ_HEAD; k->start = Curl_now(); /* start time */ k->now = k->start; /* current time is now */ k->header = TRUE; /* assume header */ - k->bytecount = 0; - - k->buf = data->state.buffer; - k->hbufp = data->state.headerbuff; k->ignorebody = FALSE; Curl_speedinit(data); - Curl_pgrsSetUploadCounter(data, 0); Curl_pgrsSetDownloadCounter(data, 0); |