diff options
-rw-r--r-- | lib/connect.c | 4 | ||||
-rw-r--r-- | lib/ftp.c | 6 | ||||
-rw-r--r-- | lib/hostares.c | 4 | ||||
-rw-r--r-- | lib/hostthre.c | 4 | ||||
-rw-r--r-- | lib/http.c | 9 | ||||
-rw-r--r-- | lib/http_negotiate.c | 4 | ||||
-rw-r--r-- | lib/ldap.c | 4 | ||||
-rw-r--r-- | lib/ssluse.c | 22 | ||||
-rw-r--r-- | lib/transfer.c | 2 | ||||
-rw-r--r-- | lib/url.c | 251 | ||||
-rw-r--r-- | lib/urldata.h | 23 |
11 files changed, 178 insertions, 155 deletions
diff --git a/lib/connect.c b/lib/connect.c index e55464cdf..c7dee3ce2 100644 --- a/lib/connect.c +++ b/lib/connect.c @@ -479,7 +479,7 @@ CURLcode Curl_is_connected(struct connectdata *conn, else if(1 != rc) { int error = Curl_ourerrno(); failf(data, "Failed connect to %s:%d; %s", - conn->hostname, conn->port, Curl_strerror(conn,error)); + conn->host.name, conn->port, Curl_strerror(conn,error)); return CURLE_COULDNT_CONNECT; } /* @@ -576,7 +576,7 @@ CURLcode Curl_connecthost(struct connectdata *conn, /* context */ } } - hostname = data->change.proxy?conn->proxyhost:conn->hostname; + hostname = data->change.proxy?conn->proxy.name:conn->host.name; infof(data, "About to connect() to %s port %d\n", hostname, port); @@ -489,7 +489,7 @@ CURLcode Curl_ftp_connect(struct connectdata *conn) if (data->set.tunnel_thru_httpproxy) { /* We want "seamless" FTP operations through HTTP proxy tunnel */ result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET, - conn->hostname, conn->remote_port); + conn->host.name, conn->remote_port); if(CURLE_OK != result) return result; } @@ -1619,7 +1619,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn, newport = num; /* we should use the same host we already are connected to */ - newhostp = conn->hostname; + newhostp = conn->host.name; } } else @@ -1641,7 +1641,7 @@ CURLcode ftp_use_pasv(struct connectdata *conn, * We don't want to rely on a former host lookup that might've expired * now, instead we remake the lookup here and now! */ - rc = Curl_resolv(conn, conn->proxyhost, conn->port, &addr); + rc = Curl_resolv(conn, conn->proxy.name, conn->port, &addr); if(rc == CURLRESOLV_PENDING) rc = Curl_wait_for_resolv(conn, &addr); diff --git a/lib/hostares.c b/lib/hostares.c index d2ea98ea0..35640d5b7 100644 --- a/lib/hostares.c +++ b/lib/hostares.c @@ -233,11 +233,11 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, if(!conn->async.dns) { /* a name was not resolved */ if((timeout < 0) || (conn->async.status == ARES_ETIMEOUT)) { - failf(data, "Resolving host timed out: %s", conn->hostname); + failf(data, "Resolving host timed out: %s", conn->host.name); rc = CURLE_OPERATION_TIMEDOUT; } else if(conn->async.done) { - failf(data, "Could not resolve host: %s (%s)", conn->hostname, + failf(data, "Could not resolve host: %s (%s)", conn->host.name, ares_strerror(conn->async.status)); rc = CURLE_COULDNT_RESOLVE_HOST; } diff --git a/lib/hostthre.c b/lib/hostthre.c index 6f2182e03..b6c04c1af 100644 --- a/lib/hostthre.c +++ b/lib/hostthre.c @@ -375,12 +375,12 @@ CURLcode Curl_wait_for_resolv(struct connectdata *conn, if (!conn->async.dns) { /* a name was not resolved */ if (td->thread_status == (DWORD)-1 || conn->async.status == NO_DATA) { - failf(data, "Resolving host timed out: %s", conn->hostname); + failf(data, "Resolving host timed out: %s", conn->host.name); rc = CURLE_OPERATION_TIMEDOUT; } else if(conn->async.done) { failf(data, "Could not resolve host: %s; %s", - conn->hostname, Curl_strerror(conn,conn->async.status)); + conn->host.name, Curl_strerror(conn,conn->async.status)); rc = CURLE_COULDNT_RESOLVE_HOST; } else diff --git a/lib/http.c b/lib/http.c index 4cc813e98..4c517eb0e 100644 --- a/lib/http.c +++ b/lib/http.c @@ -253,7 +253,7 @@ static CURLcode http_auth_headers(struct connectdata *conn, host due to a location-follow, we do some weirdo checks here */ if(!data->state.this_is_a_follow || !data->state.auth_host || - curl_strequal(data->state.auth_host, TRUE_HOSTNAME(conn)) || + curl_strequal(data->state.auth_host, conn->host.name) || data->set.http_disable_hostname_check_before_authentication) { /* Send proxy authentication header if needed */ @@ -1113,7 +1113,8 @@ CURLcode Curl_http_connect(struct connectdata *conn) /* either HTTPS over proxy, OR explicitly asked for a tunnel */ result = Curl_ConnectHTTPProxyTunnel(conn, FIRSTSOCKET, - TRUE_HOSTNAME(conn), conn->remote_port); + conn->host.name, + conn->remote_port); if(CURLE_OK != result) return result; } @@ -1132,7 +1133,7 @@ CURLcode Curl_http_connect(struct connectdata *conn) /* Free to avoid leaking memory on multiple requests*/ free(data->state.auth_host); - data->state.auth_host = strdup(TRUE_HOSTNAME(conn)); + data->state.auth_host = strdup(conn->host.name); } return CURLE_OK; @@ -1219,7 +1220,7 @@ CURLcode Curl_http(struct connectdata *conn) struct HTTP *http; struct Cookie *co=NULL; /* no cookies from start */ char *ppath = conn->path; - char *host = TRUE_HOSTNAME(conn); + char *host = conn->host.name; const char *te = ""; /* tranfer-encoding */ char *ptr; char *request; diff --git a/lib/http_negotiate.c b/lib/http_negotiate.c index 2dc09eed3..df0d6ab84 100644 --- a/lib/http_negotiate.c +++ b/lib/http_negotiate.c @@ -71,10 +71,10 @@ get_gss_name(struct connectdata *conn, gss_name_t *server) else service = "http"; - token.length = strlen(service) + 1 + strlen(conn->hostname) + 1; + token.length = strlen(service) + 1 + strlen(conn->host.name) + 1; if (token.length + 1 > sizeof(name)) return EMSGSIZE; - sprintf(name, "%s@%s", service, conn->hostname); + sprintf(name, "%s@%s", service, conn->host.name); token.value = (void *) name; major_status = gss_import_name(&minor_status, diff --git a/lib/ldap.c b/lib/ldap.c index cb2ba0101..6e755f44e 100644 --- a/lib/ldap.c +++ b/lib/ldap.c @@ -196,10 +196,10 @@ CURLcode Curl_ldap(struct connectdata *conn) DYNA_GET_FUNCTION(void (*)(void *), ldap_memfree); DYNA_GET_FUNCTION(void (*)(void *, int), ber_free); - server = ldap_init(conn->hostname, conn->port); + server = ldap_init(conn->host.name, conn->port); if (server == NULL) { failf(data, "LDAP: Cannot connect to %s:%d", - conn->hostname, conn->port); + conn->host.name, conn->port); status = CURLE_COULDNT_CONNECT; } else { diff --git a/lib/ssluse.c b/lib/ssluse.c index 55888c08b..fa8a9fc80 100644 --- a/lib/ssluse.c +++ b/lib/ssluse.c @@ -544,7 +544,7 @@ static int Get_SSL_Session(struct connectdata *conn, if(!check->sessionid) /* not session ID means blank entry */ continue; - if(curl_strequal(conn->hostname, check->name) && + if(curl_strequal(conn->host.name, check->name) && (conn->remote_port == check->remote_port) && Curl_ssl_config_matches(&conn->ssl_config, &check->ssl_config)) { /* yes, we have a session ID! */ @@ -662,7 +662,7 @@ static int Store_SSL_Session(struct connectdata *conn, /* now init the session struct wisely */ store->sessionid = ssl_sessionid; store->age = data->state.sessionage; /* set current age */ - store->name = strdup(conn->hostname); /* clone host name */ + store->name = strdup(conn->host.name); /* clone host name */ store->remote_port = conn->remote_port; /* port number */ Curl_clone_ssl_config(&conn->ssl_config, &store->ssl_config); @@ -796,13 +796,13 @@ static CURLcode verifyhost(struct connectdata *conn, #ifdef ENABLE_IPV6 if(conn->bits.ipv6_ip && - Curl_inet_pton(AF_INET6, conn->hostname, &addr)) { + Curl_inet_pton(AF_INET6, conn->host.name, &addr)) { target = GEN_IPADD; addrlen = sizeof(struct in6_addr); } else #endif - if(Curl_inet_pton(AF_INET, conn->hostname, &addr)) { + if(Curl_inet_pton(AF_INET, conn->host.name, &addr)) { target = GEN_IPADD; addrlen = sizeof(struct in_addr); } @@ -818,8 +818,8 @@ static CURLcode verifyhost(struct connectdata *conn, int i; if(GEN_DNS == target) { - hostlen = (int)strlen(conn->hostname); - domain = strchr(conn->hostname, '.'); + hostlen = (int)strlen(conn->host.name); + domain = strchr(conn->host.name, '.'); if(domain) domainlen = (int)strlen(domain); } @@ -843,7 +843,7 @@ static CURLcode verifyhost(struct connectdata *conn, case GEN_DNS: /* name comparison */ /* Is this an exact match? */ if((hostlen == altlen) && - curl_strnequal(conn->hostname, altptr, hostlen)) + curl_strnequal(conn->host.name, altptr, hostlen)) matched = TRUE; /* Is this a wildcard match? */ @@ -867,7 +867,7 @@ static CURLcode verifyhost(struct connectdata *conn, if(matched) /* an alternative name matched the server hostname */ - infof(data, "\t subjectAltName: %s matched\n", conn->hostname); + infof(data, "\t subjectAltName: %s matched\n", conn->host.name); else { bool obtain=FALSE; if(X509_NAME_get_text_by_NID(X509_get_subject_name(server_cert), @@ -889,15 +889,15 @@ static CURLcode verifyhost(struct connectdata *conn, obtain = TRUE; if(obtain) { - if(!cert_hostcheck(peer_CN, conn->hostname)) { + if(!cert_hostcheck(peer_CN, conn->host.name)) { if(data->set.ssl.verifyhost > 1) { failf(data, "SSL: certificate subject name '%s' does not match " - "target host name '%s'", peer_CN, conn->hostname); + "target host name '%s'", peer_CN, conn->host.name); return CURLE_SSL_PEER_CERTIFICATE; } else infof(data, "\t common name: %s (does not match '%s')\n", - peer_CN, conn->hostname); + peer_CN, conn->host.name); } else infof(data, "\t common name: %s (matched)\n", peer_CN); diff --git a/lib/transfer.c b/lib/transfer.c index c46ed3061..3df1f1fd0 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -805,7 +805,7 @@ CURLcode Curl_readwrite(struct connectdata *conn, /* If there is a custom-set Host: name, use it here, or else use real peer host name. */ conn->allocptr.cookiehost? - conn->allocptr.cookiehost:conn->hostname, + conn->allocptr.cookiehost:conn->host.name, conn->path); Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE); } @@ -149,10 +149,6 @@ static unsigned int ConnectionStore(struct SessionHandle *data, struct connectdata *conn); static bool safe_strequal(char* str1, char* str2); -#ifdef USE_LIBIDN -static bool is_ASCII_name(const char *hostname); -#endif - #ifndef USE_ARES /* not for Win32, unless it is cygwin not for ares builds */ @@ -1369,10 +1365,17 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->proto.generic); Curl_safefree(conn->newurl); Curl_safefree(conn->pathbuffer); /* the URL path buffer */ - Curl_safefree(conn->namebuffer); /* the URL host name buffer */ -#ifdef USE_LIBIDN - Curl_safefree(conn->ace_hostname); -#endif + + Curl_safefree(conn->host.rawalloc); /* host name buffer */ + Curl_safefree(conn->proxy.rawalloc); /* proxy name buffer */ + if(conn->host.encalloc) + (free)(conn->host.encalloc); /* encoded host name buffer, must be freed + with free() since this was allocated by + libidn */ + if(conn->proxy.encalloc) + (free)(conn->proxy.encalloc); /* encoded proxy name buffer, must be freed + with free() since this was allocated by + libidn */ Curl_SSL_Close(conn); /* close possibly still open sockets */ @@ -1394,7 +1397,7 @@ CURLcode Curl_disconnect(struct connectdata *conn) Curl_safefree(conn->allocptr.cookie); Curl_safefree(conn->allocptr.host); Curl_safefree(conn->allocptr.cookiehost); - Curl_safefree(conn->proxyhost); + #if defined(USE_ARES) || defined(USE_THREADING_GETHOSTBYNAME) || \ defined(USE_THREADING_GETADDRINFO) /* possible left-overs from the async name resolve */ @@ -1473,7 +1476,7 @@ ConnectionExists(struct SessionHandle *data, continue; if(strequal(needle->protostr, check->protostr) && - strequal(TRUE_HOSTNAME(needle), TRUE_HOSTNAME(check)) && + strequal(needle->host.name, check->host.name) && (needle->remote_port == check->remote_port) ) { if(needle->protocol & PROT_SSL) { /* This is SSL, verify that we're using the same @@ -1500,7 +1503,7 @@ ConnectionExists(struct SessionHandle *data, else { /* The requested needle connection is using a proxy, is the checked one using the same? */ if(check->bits.httpproxy && - strequal(needle->proxyhost, check->proxyhost) && + strequal(needle->proxy.name, check->proxy.name) && needle->port == check->port) { /* This is the same proxy connection, use it! */ match = TRUE; @@ -1763,7 +1766,7 @@ static int handleSock5Proxy(const char *proxy_name, #ifndef ENABLE_IPV6 struct Curl_dns_entry *dns; Curl_addrinfo *hp=NULL; - int rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->remote_port, &dns); + int rc = Curl_resolv(conn, conn->host.name, conn->remote_port, &dns); if(rc == CURLRESOLV_ERROR) return 1; @@ -1788,7 +1791,7 @@ static int handleSock5Proxy(const char *proxy_name, } else { failf(conn->data, "Failed to resolve \"%s\" for SOCKS5 connect.", - conn->hostname); + conn->host.name); return 1; } #else @@ -1906,7 +1909,7 @@ static void verboseconnect(struct connectdata *conn) host = Curl_inet_ntop(AF_INET, &in, addrbuf, sizeof(addrbuf)); #endif infof(data, "Connected to %s (%s) port %d\n", - conn->bits.httpproxy?conn->proxyhost:conn->hostname, + conn->bits.httpproxy?conn->proxy.dispname:conn->host.dispname, host?host:"", conn->port); } @@ -1950,6 +1953,50 @@ CURLcode Curl_protocol_connect(struct connectdata *conn) return result; /* pass back status */ } +/* + * Helpers for IDNA convertions. + */ +#ifdef USE_LIBIDN +static bool is_ASCII_name (const char *hostname) +{ + const unsigned char *ch = (const unsigned char*)hostname; + + while (*ch) { + if (*ch++ & 0x80) + return FALSE; + } + return TRUE; +} +#endif + +static void fix_hostname(struct connectdata *conn, struct hostname *host) +{ + /* set the name we use to display the host name */ + conn->host.dispname = conn->host.name; + +#ifdef USE_LIBIDN + /************************************************************* + * Check name for non-ASCII and convert hostname to ACE form. + *************************************************************/ + if (!is_ASCII_name(host->name)) { + char *ace_hostname = NULL; + struct SessionHandle *data = conn->data; + int rc = idna_to_ascii_lz(host->name, &ace_hostname, 0); + infof (data, "Input domain encoded as `%s'\n", + stringprep_locale_charset ()); + if (rc != IDNA_SUCCESS) + infof(data, "Failed to convert %s to ACE; IDNA error %d\n", + host->name, rc); + else { + host->encalloc = ace_hostname; + /* change the name pointer to point to the encoded hostname */ + host->name = host->encalloc; + } + } +#endif +} + + /** * CreateConnection() sets up a new connectdata struct, or re-uses an already * existing one, and resolves host name. @@ -2075,10 +2122,10 @@ static CURLcode CreateConnection(struct SessionHandle *data, return CURLE_OUT_OF_MEMORY; /* really bad error */ conn->path = conn->pathbuffer; - conn->namebuffer=(char *)malloc(urllen); - if(NULL == conn->namebuffer) + conn->host.rawalloc=(char *)malloc(urllen); + if(NULL == conn->host.rawalloc) return CURLE_OUT_OF_MEMORY; - conn->hostname = conn->namebuffer; + conn->host.name = conn->host.rawalloc; /************************************************************* * Parse the URL. @@ -2139,9 +2186,9 @@ static CURLcode CreateConnection(struct SessionHandle *data, strcpy(conn->protostr, "file"); /* store protocol string lowercase */ } else { - /* Set default host and default path */ - strcpy(conn->namebuffer, "curl.haxx.se"); + /* Set default path */ strcpy(conn->path, "/"); + /* We need to search for '/' OR '?' - whichever comes first after host * name but before the path. We need to change that to handle things like * http://example.com?param= (notice the missing '/'). Later we'll insert @@ -2150,14 +2197,14 @@ static CURLcode CreateConnection(struct SessionHandle *data, if (2 > sscanf(data->change.url, "%64[^\n:]://%[^\n/?]%[^\n]", conn->protostr, - conn->namebuffer, conn->path)) { + conn->host.name, conn->path)) { /* * The URL was badly formatted, let's try the browser-style _without_ * protocol specified like 'http://'. */ if((1 > sscanf(data->change.url, "%[^\n/?]%[^\n]", - conn->namebuffer, conn->path)) ) { + conn->host.name, conn->path)) ) { /* * We couldn't even get this format. */ @@ -2173,21 +2220,21 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* Note: if you add a new protocol, please update the list in * lib/version.c too! */ - if(checkprefix("GOPHER", conn->namebuffer)) + if(checkprefix("GOPHER", conn->host.name)) strcpy(conn->protostr, "gopher"); #ifdef USE_SSLEAY - else if(checkprefix("HTTPS", conn->namebuffer)) + else if(checkprefix("HTTPS", conn->host.name)) strcpy(conn->protostr, "https"); - else if(checkprefix("FTPS", conn->namebuffer)) + else if(checkprefix("FTPS", conn->host.name)) strcpy(conn->protostr, "ftps"); #endif /* USE_SSLEAY */ - else if(checkprefix("FTP", conn->namebuffer)) + else if(checkprefix("FTP", conn->host.name)) strcpy(conn->protostr, "ftp"); - else if(checkprefix("TELNET", conn->namebuffer)) + else if(checkprefix("TELNET", conn->host.name)) strcpy(conn->protostr, "telnet"); - else if (checkprefix("DICT", conn->namebuffer)) + else if (checkprefix("DICT", conn->host.name)) strcpy(conn->protostr, "DICT"); - else if (checkprefix("LDAP", conn->namebuffer)) + else if (checkprefix("LDAP", conn->host.name)) strcpy(conn->protostr, "LDAP"); else { strcpy(conn->protostr, "http"); @@ -2212,7 +2259,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* * So if the URL was A://B/C, * conn->protostr is A - * conn->namebuffer is B + * conn->host.name is B * conn->path is /C */ @@ -2275,15 +2322,15 @@ static CURLcode CreateConnection(struct SessionHandle *data, nope=no_proxy?strtok_r(no_proxy, ", ", &no_proxy_tok_buf):NULL; while(nope) { unsigned int namelen; - char *endptr = strchr(conn->hostname, ':'); + char *endptr = strchr(conn->host.name, ':'); if(endptr) - namelen=endptr-conn->hostname; + namelen=endptr-conn->host.name; else - namelen=strlen(conn->hostname); + namelen=strlen(conn->host.name); if(strlen(nope) <= namelen) { char *checkn= - conn->hostname + namelen - strlen(nope); + conn->host.name + namelen - strlen(nope); if(checkprefix(nope, checkn)) { /* no proxy for this host! */ break; @@ -2546,7 +2593,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * we'll try to get now! */ type=strstr(conn->path, ";type="); if(!type) { - type=strstr(conn->namebuffer, ";type="); + type=strstr(conn->host.rawalloc, ";type="); } if(type) { char command; @@ -2655,23 +2702,23 @@ static CURLcode CreateConnection(struct SessionHandle *data, * To be able to detect port number flawlessly, we must not confuse them * IPv6-specified addresses in the [0::1] style. (RFC2732) * - * The conn->hostname is currently [user:passwd@]host[:port] where host + * The conn->host.name is currently [user:passwd@]host[:port] where host * could be a hostname, IPv4 address or IPv6 address. *************************************************************/ - if((1 == sscanf(conn->hostname, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && + if((1 == sscanf(conn->host.name, "[%*39[0-9a-fA-F:.]%c", &endbracket)) && (']' == endbracket)) { /* this is a RFC2732-style specified IP-address */ conn->bits.ipv6_ip = TRUE; - conn->hostname++; /* pass the starting bracket */ - tmp = strchr(conn->hostname, ']'); + conn->host.name++; /* pass the starting bracket */ + tmp = strchr(conn->host.name, ']'); *tmp = 0; /* zero terminate */ tmp++; /* pass the ending bracket */ if(':' != *tmp) tmp = NULL; /* no port number available */ } else - tmp = strrchr(conn->hostname, ':'); + tmp = strrchr(conn->host.name, ':'); if (tmp) { char *rest; @@ -2740,7 +2787,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, } /* now, clone the cleaned proxy host name */ - conn->proxyhost = strdup(proxyptr); + conn->proxy.rawalloc = strdup(proxyptr); + conn->proxy.name = conn->proxy.rawalloc; free(proxydup); /* free the duplicate pointer and not the modified */ } @@ -2753,7 +2801,7 @@ static CURLcode CreateConnection(struct SessionHandle *data, * Inputs: data->set.userpwd (CURLOPT_USERPWD) * data->set.fpasswd (CURLOPT_PASSWDFUNCTION) * data->set.use_netrc (CURLOPT_NETRC) - * conn->hostname + * conn->host.name * netrc file * hard-coded defaults * @@ -2761,11 +2809,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, * conn->bits.user_passwd - non-zero if non-default passwords exist * conn->user - non-zero length if defined * conn->passwd - ditto - * conn->hostname - remove user name and password + * conn->host.name - remove user name and password */ /* At this point, we're hoping all the other special cases have - * been taken care of, so conn->hostname is at most + * been taken care of, so conn->host.name is at most * [user[:password]]@]hostname * * We need somewhere to put the embedded details, so do that first. @@ -2778,12 +2826,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* This is a FTP or HTTP URL, we will now try to extract the possible * user+password pair in a string like: * ftp://user:password@ftp.my.site:8021/README */ - char *ptr=strchr(conn->hostname, '@'); - char *userpass = conn->hostname; + char *ptr=strchr(conn->host.name, '@'); + char *userpass = conn->host.name; if(ptr != NULL) { /* there's a user+password given here, to the left of the @ */ - conn->hostname = ++ptr; + conn->host.name = ++ptr; /* So the hostname is sane. Only bother interpreting the * results if we could care. It could still be wasted @@ -2844,11 +2892,11 @@ static CURLcode CreateConnection(struct SessionHandle *data, } if (data->set.use_netrc != CURL_NETRC_IGNORED) { - if(Curl_parsenetrc(conn->hostname, + if(Curl_parsenetrc(conn->host.name, user, passwd, data->set.netrc_file)) { infof(data, "Couldn't find host %s in the .netrc file, using defaults\n", - conn->hostname); + conn->host.name); } else conn->bits.user_passwd = 1; /* enable user+password */ @@ -2898,8 +2946,8 @@ static CURLcode CreateConnection(struct SessionHandle *data, */ struct connectdata *old_conn = conn; - if(old_conn->proxyhost) - free(old_conn->proxyhost); + if(old_conn->proxy.rawalloc) + free(old_conn->proxy.rawalloc); /* free the SSL config struct from this connection struct as this was allocated in vain and is targeted for destruction */ @@ -2915,13 +2963,12 @@ static CURLcode CreateConnection(struct SessionHandle *data, /* get the newly set value, not the old one */ conn->bits.no_body = old_conn->bits.no_body; - free(conn->namebuffer); /* free the newly allocated name buffer */ - conn->namebuffer = old_conn->namebuffer; /* use the old one */ - conn->hostname = old_conn->hostname; -#ifdef USE_LIBIDN - Curl_safefree(conn->ace_hostname); - conn->ace_hostname = old_conn->ace_hostname; -#endif + free(conn->host.rawalloc); /* free the newly allocated name buffer */ + conn->host.rawalloc = old_conn->host.rawalloc; /* use the old one */ + conn->host.name = old_conn->host.name; + + conn->host.encalloc = old_conn->host.encalloc; /* use the old one */ + conn->host.dispname = old_conn->host.dispname; free(conn->pathbuffer); /* free the newly allocated path pointer */ conn->pathbuffer = old_conn->pathbuffer; /* use the old one */ @@ -3056,35 +3103,45 @@ static CURLcode CreateConnection(struct SessionHandle *data, conn->connect_addr = NULL; /* we don't connect now so we don't have any fresh connect_addr struct to point to */ } - else if(!data->change.proxy || !*data->change.proxy) { - /* If not connecting via a proxy, extract the port from the URL, if it is - * there, thus overriding any defaults that might have been set above. */ - conn->port = conn->remote_port; /* it is the same port */ + else { + /* this is a fresh connect */ - /* Resolve target host right on */ - rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), conn->port, &hostaddr); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; + /* set a pointer to the hostname we display */ + fix_hostname(conn, &conn->host); + + if(!data->change.proxy || !*data->change.proxy) { + /* If not connecting via a proxy, extract the port from the URL, if it is + * there, thus overriding any defaults that might have been set above. */ + conn->port = conn->remote_port; /* it is the same port */ + + /* Resolve target host right on */ + rc = Curl_resolv(conn, conn->host.name, conn->port, &hostaddr); + if(rc == CURLRESOLV_PENDING) + *async = TRUE; - else if(!hostaddr) { - failf(data, "Couldn't resolve host '%s'", conn->hostname); - result = CURLE_COULDNT_RESOLVE_HOST; - /* don't return yet, we need to clean up the timeout first */ + else if(!hostaddr) { + failf(data, "Couldn't resolve host '%s'", conn->host.dispname); + result = CURLE_COULDNT_RESOLVE_HOST; + /* don't return yet, we need to clean up the timeout first */ + } } - } - else { - /* This is a proxy that hasn't been resolved yet. */ + else { + /* This is a proxy that hasn't been resolved yet. */ - /* resolve proxy */ - rc = Curl_resolv(conn, conn->proxyhost, conn->port, &hostaddr); + /* IDN check */ + fix_hostname(conn, &conn->proxy); - if(rc == CURLRESOLV_PENDING) - *async = TRUE; + /* resolve proxy */ + rc = Curl_resolv(conn, conn->proxy.name, conn->port, &hostaddr); - else if(!hostaddr) { - failf(data, "Couldn't resolve proxy '%s'", conn->proxyhost); - result = CURLE_COULDNT_RESOLVE_PROXY; - /* don't return yet, we need to clean up the timeout first */ + if(rc == CURLRESOLV_PENDING) + *async = TRUE; + + else if(!hostaddr) { + failf(data, "Couldn't resolve proxy '%s'", conn->proxy.dispname); + result = CURLE_COULDNT_RESOLVE_PROXY; + /* don't return yet, we need to clean up the timeout first */ + } } } *addr = hostaddr; @@ -3150,25 +3207,6 @@ static CURLcode SetupConnection(struct connectdata *conn, a file:// transfer */ return result; -#ifdef USE_LIBIDN - /************************************************************* - * Check name for non-ASCII and convert hostname to ACE form. - *************************************************************/ - - if(!conn->bits.reuse && conn->remote_port) { - const char *host = conn->hostname; - char *ace_hostname; - - if (!is_ASCII_name(host)) { - int rc = idna_to_ascii_lz (host, &ace_hostname, 0); - if (rc == IDNA_SUCCESS) - conn->ace_hostname = ace_hostname; - else - infof(data, "Failed to convert %s to ACE; IDNA error %d\n", host, rc); - } - } -#endif - /************************************************************* * Send user-agent to HTTP proxies even if the target protocol * isn't HTTP. @@ -3502,18 +3540,3 @@ void Curl_free_ssl_config(struct ssl_config_data* sslc) free(sslc->random_file); } -/* - * Helpers for IDNA convertions. - */ -#ifdef USE_LIBIDN -static bool is_ASCII_name (const char *hostname) -{ - const unsigned char *ch = (const unsigned char*)hostname; - - while (*ch) { - if (*ch++ > 0x80) - return FALSE; - } - return TRUE; -} -#endif diff --git a/lib/urldata.h b/lib/urldata.h index 1912bcf0f..19e83ca4f 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -304,6 +304,13 @@ struct ConnectBits { bool no_body; /* CURLOPT_NO_BODY (or similar) was set */ }; +struct hostname { + char *rawalloc; /* allocated "raw" version of the name */ + char *encalloc; /* allocated IDN-encoded version of the name */ + char *name; /* name to use internally, might be encoded, might be raw */ + char *dispname; /* name to display, as 'name' might be encoded */ +}; + /* * This struct is all the previously local variables from Curl_perform() moved * to struct to allow the function to return and get re-invoked better without @@ -428,16 +435,10 @@ struct connectdata { struct sockaddr_in serv_addr; #endif char protostr[64]; /* store the protocol string in this buffer */ - char *namebuffer; /* allocated buffer to store the hostname in */ - char *hostname; /* hostname to use, as parsed from url. points to - somewhere within the namebuffer[] area */ -#ifdef USE_LIBIDN - char *ace_hostname; /* hostname possibly converted to ACE form */ -#define TRUE_HOSTNAME(conn) \ - (conn->ace_hostname ? conn->ace_hostname : conn->hostname) -#else -#define TRUE_HOSTNAME(conn) conn->hostname -#endif + + struct hostname host; + struct hostname proxy; + char *pathbuffer;/* allocated buffer to store the URL's path part in */ char *path; /* path to use, points to somewhere within the pathbuffer area */ @@ -456,8 +457,6 @@ struct connectdata { this syntax. */ curl_off_t resume_from; /* continue [ftp] transfer from here */ - char *proxyhost; /* name of the http proxy host */ - char *user; /* user name string, allocated */ char *passwd; /* password string, allocated */ |