diff --git a/lib/http.c b/lib/http.c index 6ccc273d13..ca229144ed 100644 --- a/lib/http.c +++ b/lib/http.c @@ -2068,9 +2068,9 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data) } } else { - /* When building Host: headers, we must put the hostname within - [brackets] if the hostname is a plain IPv6-address. RFC2732-style. */ - const char *host = conn->host.name; + /* Use the hostname as present in the URL if it was IPv6. */ + char *host = (data->state.up.hostname[0] == '[') ? + data->state.up.hostname : conn->host.name; if(((conn->given->protocol & (CURLPROTO_HTTPS | CURLPROTO_WSS)) && (conn->remote_port == PORT_HTTPS)) || @@ -2078,14 +2078,9 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data) (conn->remote_port == PORT_HTTP))) /* if(HTTPS on port 443) OR (HTTP on port 80) then do not include the port number in the host string */ - aptr->host = curl_maprintf("Host: %s%s%s\r\n", - conn->bits.ipv6_ip ? "[" : "", - host, conn->bits.ipv6_ip ? "]" : ""); + aptr->host = curl_maprintf("Host: %s\r\n", host); else - aptr->host = curl_maprintf("Host: %s%s%s:%d\r\n", - conn->bits.ipv6_ip ? "[" : "", - host, conn->bits.ipv6_ip ? "]" : "", - conn->remote_port); + aptr->host = curl_maprintf("Host: %s:%d\r\n", host, conn->remote_port); if(!aptr->host) /* without Host: we cannot make a nice request */ diff --git a/lib/http_proxy.c b/lib/http_proxy.c index a9521c92da..5ebac8d2df 100644 --- a/lib/http_proxy.c +++ b/lib/http_proxy.c @@ -183,10 +183,7 @@ void Curl_http_proxy_get_destination(struct Curl_cfilter *cf, else *pport = cf->conn->remote_port; - if(*phostname != cf->conn->host.name) - *pipv6_ip = (strchr(*phostname, ':') != NULL); - else - *pipv6_ip = (bool)cf->conn->bits.ipv6_ip; + *pipv6_ip = (strchr(*phostname, ':') != NULL); } struct cf_proxy_ctx { diff --git a/lib/openldap.c b/lib/openldap.c index f05a2ab05c..7d038e0bf2 100644 --- a/lib/openldap.c +++ b/lib/openldap.c @@ -614,11 +614,10 @@ static CURLcode oldap_connect(struct Curl_easy *data, bool *done) if(result) goto out; - hosturl = curl_maprintf("%s://%s%s%s:%d", + hosturl = curl_maprintf("%s://%s:%d", conn->scheme->name, - conn->bits.ipv6_ip ? "[" : "", - conn->host.name, - conn->bits.ipv6_ip ? "]" : "", + (data->state.up.hostname[0] == '[') ? + data->state.up.hostname : conn->host.name, conn->remote_port); if(!hosturl) { result = CURLE_OUT_OF_MEMORY; diff --git a/lib/socks.c b/lib/socks.c index b7c3bd6146..0fcd99828b 100644 --- a/lib/socks.c +++ b/lib/socks.c @@ -790,7 +790,7 @@ static CURLproxycode socks5_req1_init(struct socks_state *sx, /* remote resolving, send what type+addr/string to resolve */ #ifdef USE_IPV6 - if(cf->conn->bits.ipv6_ip) { + if(strchr(sx->hostname, ':')) { desttype = 4; destination = ipbuf; destlen = 16; diff --git a/lib/url.c b/lib/url.c index 407e0f4d0c..ab025a26af 100644 --- a/lib/url.c +++ b/lib/url.c @@ -1609,6 +1609,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, CURLU *uh; CURLUcode uc; char *hostname; + size_t hlen; bool use_set_uh = (data->set.uh && !data->state.this_is_a_follow); up_free(data); /* cleanup previous leftovers first */ @@ -1667,17 +1668,16 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, failf(data, "Too long hostname (maximum is %d)", MAX_URL_LEN); return CURLE_URL_MALFORMAT; } + hostname = data->state.up.hostname; + hlen = hostname ? strlen(hostname) : 0; if(hostname && hostname[0] == '[') { /* This looks like an IPv6 address literal. See if there is an address scope. */ - size_t hlen; - conn->bits.ipv6_ip = TRUE; - /* cut off the brackets! */ + /* cut off the brackets after copying this! */ hostname++; - hlen = strlen(hostname); - hostname[hlen - 1] = 0; + hlen -= 2; zonefrom_url(uh, data, conn); } @@ -1686,6 +1686,7 @@ static CURLcode parseurlandfillconn(struct Curl_easy *data, conn->host.rawalloc = curlx_strdup(hostname ? hostname : ""); if(!conn->host.rawalloc) return CURLE_OUT_OF_MEMORY; + conn->host.rawalloc[hlen] = 0; /* cut off for ipv6 case */ conn->host.name = conn->host.rawalloc; /************************************************************* @@ -2817,19 +2818,14 @@ static CURLcode parse_connect_to_string(struct Curl_easy *data, ptr++; } else { - /* check whether the URL's hostname matches */ - size_t hostname_to_match_len; - char *hostname_to_match = curl_maprintf("%s%s%s", - conn->bits.ipv6_ip ? "[" : "", - conn->host.name, - conn->bits.ipv6_ip ? "]" : ""); - if(!hostname_to_match) - return CURLE_OUT_OF_MEMORY; - hostname_to_match_len = strlen(hostname_to_match); - host_match = curl_strnequal(ptr, hostname_to_match, - hostname_to_match_len); - curlx_free(hostname_to_match); - ptr += hostname_to_match_len; + /* check whether the URL's hostname matches. Use the url hostname + * when it was an IPv6 address. Otherwise use the connection's hostname + * that has IDN conversion. */ + char *hostname_to_match = (data->state.up.hostname[0] == '[') ? + data->state.up.hostname : conn->host.name; + size_t hlen = strlen(hostname_to_match); + host_match = curl_strnequal(ptr, hostname_to_match, hlen); + ptr += hlen; host_match = host_match && *ptr == ':'; ptr++; diff --git a/lib/urldata.h b/lib/urldata.h index 53ca29edf7..0f73121282 100644 --- a/lib/urldata.h +++ b/lib/urldata.h @@ -338,8 +338,6 @@ struct ConnectBits { that overrides the host in the URL */ BIT(conn_to_port); /* if set, this connection has a "connect to port" that overrides the port in the URL (remote port) */ - BIT(ipv6_ip); /* we communicate with a remote site specified with pure IPv6 - IP address */ BIT(ipv6); /* we communicate with a site using an IPv6 address */ BIT(do_more); /* this is set TRUE if the ->curl_do_more() function is supposed to be called, after ->curl_do() */ diff --git a/lib/vssh/libssh.c b/lib/vssh/libssh.c index 6554e55dcd..3bc4bd146f 100644 --- a/lib/vssh/libssh.c +++ b/lib/vssh/libssh.c @@ -2422,13 +2422,9 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done) return CURLE_FAILED_INIT; } - if(conn->bits.ipv6_ip) { - char ipv6[MAX_IPADR_LEN]; - curl_msnprintf(ipv6, sizeof(ipv6), "[%s]", conn->host.name); - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_HOST, ipv6); - } - else - rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_HOST, conn->host.name); + rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_HOST, + (data->state.up.hostname[0] == '[') ? + data->state.up.hostname : conn->host.name); if(rc != SSH_OK) { failf(data, "Could not set remote host"); diff --git a/tests/data/test2053 b/tests/data/test2053 index 34533951e4..8e53cd741f 100644 --- a/tests/data/test2053 +++ b/tests/data/test2053 @@ -31,7 +31,7 @@ Connect to specific host with IP addresses http://10.0.0.1:8081/%TESTNUMBER --connect-to 10.0.0.1:8081:%HOSTIP:%HTTPPORT --next -http://[fc00::1]:8082/%TESTNUMBER --connect-to [fc00::1]:8082:%HOSTIP:%HTTPPORT +http://[fc00::1]:8081/%TESTNUMBER --connect-to [fc00::1]:8081:%HOSTIP:%HTTPPORT @@ -44,7 +44,7 @@ User-Agent: curl/%VERSION Accept: */* GET /%TESTNUMBER HTTP/1.1 -Host: [fc00::1]:8082 +Host: [fc00::1]:8081 User-Agent: curl/%VERSION Accept: */*