mirror of
https://github.com/curl/curl.git
synced 2024-11-21 01:16:58 +08:00
Made host name and proxy name get stored in a 'struct hostname' and set
all things up to work with encoded host names internally, as well as keeping 'display names' to show in debug messages. IDN resolves work for me now using ipv6, ipv4 and ares resolving. Even cookies on IDN sites seem to do right.
This commit is contained in:
parent
96002646f1
commit
4b9f8e766d
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -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 {
|
||||
|
22
lib/ssluse.c
22
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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
255
lib/url.c
255
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 */
|
||||
|
||||
/* Resolve target host right on */
|
||||
rc = Curl_resolv(conn, TRUE_HOSTNAME(conn), 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 {
|
||||
/* This is a proxy that hasn't been resolved yet. */
|
||||
/* this is a fresh connect */
|
||||
|
||||
/* resolve proxy */
|
||||
rc = Curl_resolv(conn, conn->proxyhost, conn->port, &hostaddr);
|
||||
/* set a pointer to the hostname we display */
|
||||
fix_hostname(conn, &conn->host);
|
||||
|
||||
if(rc == CURLRESOLV_PENDING)
|
||||
*async = TRUE;
|
||||
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 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 */
|
||||
/* 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->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. */
|
||||
|
||||
/* IDN check */
|
||||
fix_hostname(conn, &conn->proxy);
|
||||
|
||||
/* resolve proxy */
|
||||
rc = Curl_resolv(conn, conn->proxy.name, conn->port, &hostaddr);
|
||||
|
||||
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
|
||||
|
@ -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 */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user