mirror of
https://github.com/curl/curl.git
synced 2026-06-02 02:44:35 +03:00
urldata: connection bit ipv6_ip is wrong
Eliminate `conn->bits.ipv6_ip` The bit was only correct for the first transfer using a connection. Use `data->state.up.hostname` instead in places that need the URL hostname in its original form. Fix parseurlandfillconn() to not modify `data->state.up.hostname` before copying the connection's hostname, but modify the copy instead, leaving the URL hostname intact. Closes #20919
This commit is contained in:
parent
eb5af3a9c7
commit
412cd2577a
8 changed files with 29 additions and 48 deletions
15
lib/http.c
15
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 */
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
32
lib/url.c
32
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++;
|
||||
|
|
|
|||
|
|
@ -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() */
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ Connect to specific host with IP addresses
|
|||
|
||||
<command>
|
||||
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
|
||||
</command>
|
||||
</client>
|
||||
|
||||
|
|
@ -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: */*
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue