aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/connect.c4
-rw-r--r--lib/ftp.c6
-rw-r--r--lib/hostares.c4
-rw-r--r--lib/hostthre.c4
-rw-r--r--lib/http.c9
-rw-r--r--lib/http_negotiate.c4
-rw-r--r--lib/ldap.c4
-rw-r--r--lib/ssluse.c22
-rw-r--r--lib/transfer.c2
-rw-r--r--lib/url.c251
-rw-r--r--lib/urldata.h23
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);
diff --git a/lib/ftp.c b/lib/ftp.c
index 6333bb422..17632044b 100644
--- a/lib/ftp.c
+++ b/lib/ftp.c
@@ -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);
}
diff --git a/lib/url.c b/lib/url.c
index 695d374bf..38beb89a2 100644
--- a/lib/url.c
+++ b/lib/url.c
@@ -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 */