← Commit list

d786a85f19

Stefan Eissing
Stefan Eissing
2026-06-26
SUCCESS Duration: 178s

Subject

lib: hostname related cleanups

Binary

No binary (build failed)

Architecture & Compiler Flags

Architecture: x86_64-linux-gnu Compiler: gcc (Ubuntu 11.4.0-1ubuntu1~22.04.3) 11.4.0

—

Build Log

(log yok)

Commit Diff GitHub →

lib/http.c+37 -24
@@ -2000,17 +2000,17 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
{
struct connectdata *conn = data->conn;
struct dynamically_allocated_data *aptr = &data->state.aptr;
- const char *ptr;
+ const char *ptr = NULL;
curlx_safefree(aptr->host);
#ifndef CURL_DISABLE_COOKIES
curlx_safefree(data->req.cookiehost);
#endif
- ptr = Curl_checkheaders(data, STRCONST("Host"));
- if(ptr &&
- (!data->state.this_is_a_follow ||
- Curl_peer_equal(data->state.initial_origin, data->state.origin))) {
+ if(Curl_peer_equal(data->state.initial_origin, data->state.origin))
+ ptr = Curl_checkheaders(data, STRCONST("Host"));
+
+ if(ptr) {
#ifndef CURL_DISABLE_COOKIES
/* If we have a given custom Host: header, we extract the hostname in
order to possibly use it for cookie reasons later on. We only allow the
@@ -2047,30 +2047,40 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
#endif
if(!curl_strequal("Host:", ptr)) {
- aptr->host = curl_maprintf("Host:%s\r\n", &ptr[5]);
+ aptr->host = curl_maprintf("Host:%s", &ptr[5]);
if(!aptr->host)
return CURLE_OUT_OF_MEMORY;
}
}
else {
- /* Use the hostname as present in the URL if it was IPv6. */
- char *host = (data->state.origin->user_hostname[0] == '[') ?
- data->state.origin->user_hostname : data->state.origin->hostname;
-
- if(((conn->given->protocol & (CURLPROTO_HTTPS | CURLPROTO_WSS)) &&
- (data->state.origin->port == PORT_HTTPS)) ||
- ((conn->given->protocol & (CURLPROTO_HTTP | CURLPROTO_WS)) &&
- (data->state.origin->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\r\n", host);
- else
- aptr->host = curl_maprintf("Host: %s:%d\r\n",
- host, data->state.origin->port);
+ /* This is the HTTP Host: header, so we want
+ * - for ipv6 origins: "[ipv6-address]" where the ipv6 address is
+ * found in origin->hostname, stripped of zoneid/scopeid.
+ * - the (IDN converted) origin->hostname (DNS name or ipv4) otherwise.
+ * Note: zoneid/scopeid only applies to local routing and has no
+ * meaning on the remote HTTP server (eg. would confuse it). */
+ bool ipv6 = (bool)data->state.origin->ipv6;
+ struct dynbuf tmp;
+ size_t hlen;
+ CURLcode result;
- if(!aptr->host)
- /* without Host: we cannot make a nice request */
- return CURLE_OUT_OF_MEMORY;
+ curlx_dyn_init(&tmp, DYN_HTTP_REQUEST);
+ result = curlx_dyn_addn(&tmp, STRCONST("Host: "));
+ if(!result && ipv6)
+ result = curlx_dyn_addn(&tmp, STRCONST("["));
+ if(!result)
+ result = curlx_dyn_add(&tmp, data->state.origin->hostname);
+ if(!result && ipv6)
+ result = curlx_dyn_addn(&tmp, STRCONST("]"));
+ if(!result &&
+ ((data->state.origin->port != data->state.origin->scheme->defport) ||
+ (data->state.origin->scheme->family != conn->scheme->family))) {
+ result = curlx_dyn_addf(&tmp, ":%u", data->state.origin->port);
+ }
+
+ aptr->host = result ? NULL : curlx_dyn_take(&tmp, &hlen);
+ curlx_dyn_free(&tmp);
+ return result;
}
return CURLE_OK;
}
@@ -2896,8 +2906,11 @@ static CURLcode http_add_hd(struct Curl_easy *data,
break;
case H1_HD_HOST:
- if(data->state.aptr.host)
+ if(data->state.aptr.host) {
result = curlx_dyn_add(req, data->state.aptr.host);
+ if(!result)
+ result = curlx_dyn_addn(req, STRCONST("\r\n"));
+ }
break;
#ifndef CURL_DISABLE_PROXY
lib/http_aws_sigv4.c+2 -5
@@ -401,11 +401,8 @@ static CURLcode make_headers(struct Curl_easy *data,
if(!Curl_checkheaders(data, STRCONST("Host"))) {
char *fullhost;
- if(data->state.aptr.host) {
- /* remove /r/n as the separator for canonical request must be '\n' */
- size_t pos = strcspn(data->state.aptr.host, "\n\r");
- fullhost = curlx_memdup0(data->state.aptr.host, pos);
- }
+ if(data->state.aptr.host)
+ fullhost = curlx_strdup(data->state.aptr.host);
else
fullhost = curl_maprintf("host:%s", hostname);
lib/url.c+10 -8
@@ -1856,14 +1856,16 @@ static CURLcode parse_connect_to_string(struct Curl_easy *data,
/* 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. */
- const char *hostname_to_match = (dest->user_hostname[0] == '[') ?
- dest->user_hostname : dest->hostname;
- size_t hlen = strlen(hostname_to_match);
- host_match = curl_strnequal(ptr, hostname_to_match, hlen);
- ptr += hlen;
-
- host_match = host_match && *ptr == ':';
- ptr++;
+ size_t hlen = strlen(dest->hostname);
+ host_match = curl_strnequal(ptr, dest->hostname, hlen);
+ if(!host_match && (dest->user_hostname != dest->hostname)) {
+ /* hostname was normalized, could be IPv6 or IDN */
+ hlen = strlen(dest->user_hostname);
+ host_match = curl_strnequal(ptr, dest->user_hostname, hlen);
+ }
+ host_match = host_match && ptr[hlen] == ':';
+ if(host_match)
+ ptr += hlen + 1;
}
if(host_match) {
lib/vssh/libssh.c+2 -0
@@ -2585,6 +2585,8 @@ static CURLcode myssh_connect(struct Curl_easy *data, bool *done)
return CURLE_FAILED_INIT;
}
+ /* For ipv6 origins, use the `user_hostname` that has the "[]" enclosure.
+ * Otherwise, use `hostname` that is IDN converted. */
rc = ssh_options_set(sshc->ssh_session, SSH_OPTIONS_HOST,
conn->origin->ipv6 ?
conn->origin->user_hostname : conn->origin->hostname);