urldata: remove the aptr struct

Move the two remaining fields into the state struct instead, within the
HTTP ifdef.

Also: make the AWS sigv4 code always rely on the http_host value. It
was previously conditionally trying to also work if it was not set, but
that logic was not creating an identical copy so it would fail.

Closes #22620
This commit is contained in:
Daniel Stenberg 2026-08-18 23:58:16 +02:00
parent 79132a1daf
commit 695aa15743
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
7 changed files with 34 additions and 42 deletions

View file

@ -1840,7 +1840,7 @@ CURLcode Curl_add_custom_headers(struct Curl_easy *data,
/* only send this if the contents was non-blank or done special */
if(data->state.aptr.host &&
if(data->state.http_host &&
/* a Host: header was sent already, do not pass on any custom
Host: header as that will produce *two* in the same
request! */
@ -2017,10 +2017,9 @@ void Curl_http_method(struct Curl_easy *data,
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 = NULL;
curlx_safefree(aptr->host);
curlx_safefree(data->state.http_host);
#ifndef CURL_DISABLE_COOKIES
curlx_safefree(data->req.cookiehost);
#endif
@ -2065,8 +2064,8 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
#endif
if(!curl_strequal("Host:", ptr)) {
aptr->host = curl_maprintf("Host:%s", &ptr[5]);
if(!aptr->host)
data->state.http_host = curl_maprintf("Host:%s", &ptr[5]);
if(!data->state.http_host)
return CURLE_OUT_OF_MEMORY;
}
}
@ -2096,7 +2095,7 @@ static CURLcode http_set_aptr_host(struct Curl_easy *data)
result = curlx_dyn_addf(&tmp, ":%u", data->state.origin->port);
}
aptr->host = result ? NULL : curlx_dyn_take(&tmp, &hlen);
data->state.http_host = result ? NULL : curlx_dyn_take(&tmp, &hlen);
curlx_dyn_free(&tmp);
return result;
}
@ -2650,23 +2649,23 @@ static CURLcode http_range(struct Curl_easy *data,
if(((httpreq == HTTPREQ_GET) || (httpreq == HTTPREQ_HEAD)) &&
!Curl_checkheaders(data, STRCONST("Range"))) {
/* if a line like this was already allocated, free the previous one */
curlx_free(data->state.aptr.rangeline);
data->state.aptr.rangeline = curl_maprintf("Range: bytes=%s\r\n",
curlx_free(data->state.rangeline);
data->state.rangeline = curl_maprintf("Range: bytes=%s\r\n",
data->state.range);
if(!data->state.aptr.rangeline)
if(!data->state.rangeline)
return CURLE_OUT_OF_MEMORY;
}
else if((httpreq == HTTPREQ_POST || httpreq == HTTPREQ_PUT) &&
!Curl_checkheaders(data, STRCONST("Content-Range"))) {
curl_off_t req_clen = Curl_creader_total_length(data);
/* if a line like this was already allocated, free the previous one */
curlx_free(data->state.aptr.rangeline);
curlx_free(data->state.rangeline);
if(data->set.set_resume_from < 0) {
/* Upload resume was asked for, but we do not know the size of the
remote part so we tell the server (and act accordingly) that we
upload the whole file (again) */
data->state.aptr.rangeline =
data->state.rangeline =
curl_maprintf("Content-Range: bytes 0-%" FMT_OFF_T "/"
"%" FMT_OFF_T "\r\n", req_clen - 1, req_clen);
}
@ -2678,7 +2677,7 @@ static CURLcode http_range(struct Curl_easy *data,
curl_off_t total_len = data->req.authneg ?
data->state.infilesize :
(data->state.resume_from + req_clen);
data->state.aptr.rangeline =
data->state.rangeline =
curl_maprintf("Content-Range: bytes %s%" FMT_OFF_T "/"
"%" FMT_OFF_T "\r\n",
data->state.range, total_len - 1, total_len);
@ -2686,11 +2685,11 @@ static CURLcode http_range(struct Curl_easy *data,
else {
/* Range was selected and then we pass the incoming range and append
total size */
data->state.aptr.rangeline =
data->state.rangeline =
curl_maprintf("Content-Range: bytes %s/%" FMT_OFF_T "\r\n",
data->state.range, req_clen);
}
if(!data->state.aptr.rangeline)
if(!data->state.rangeline)
return CURLE_OUT_OF_MEMORY;
}
}
@ -2925,8 +2924,8 @@ static CURLcode http_add_hd(struct Curl_easy *data,
break;
case H1_HD_HOST:
if(data->state.aptr.host) {
result = curlx_dyn_add(req, data->state.aptr.host);
if(data->state.http_host) {
result = curlx_dyn_add(req, data->state.http_host);
if(!result)
result = curlx_dyn_addn(req, STRCONST("\r\n"));
}
@ -2945,8 +2944,8 @@ static CURLcode http_add_hd(struct Curl_easy *data,
break;
case H1_HD_RANGE:
if(data->state.use_range && data->state.aptr.rangeline)
result = curlx_dyn_add(req, data->state.aptr.rangeline);
if(data->state.use_range && data->state.rangeline)
result = curlx_dyn_add(req, data->state.rangeline);
break;
case H1_HD_USER_AGENT:

View file

@ -369,7 +369,6 @@ static CURLcode merge_duplicate_headers(struct curl_slist *head)
/* timestamp should point to a buffer of at last TIMESTAMP_SIZE bytes */
static CURLcode make_headers(struct Curl_easy *data,
const char *hostname,
char *timestamp,
const char *provider1,
size_t plen, /* length of provider1 */
@ -397,13 +396,10 @@ static CURLcode make_headers(struct Curl_easy *data,
/* provider1 lowercase */
Curl_strntolower(&date_full_hdr[2], provider1, plen);
if(!Curl_checkheaders(data, STRCONST("Host"))) {
char *fullhost;
if(data->state.aptr.host)
fullhost = curlx_strdup(data->state.aptr.host);
else
fullhost = curl_maprintf("host:%s", hostname);
if(!Curl_checkheaders(data, STRCONST("Host")) &&
data->state.http_host) {
/* Host: [host]:[port] */
char *fullhost = curlx_strdup(data->state.http_host);
if(fullhost)
head = Curl_slist_append_nodup(NULL, fullhost);
@ -933,7 +929,6 @@ static CURLcode get_timestamp(char *timestamp, size_t stampsize)
}
static CURLcode make_canonical_request(struct Curl_easy *data,
const char *hostname,
char *timestamp,
struct Curl_str *provider1,
struct Curl_str *service,
@ -953,7 +948,7 @@ static CURLcode make_canonical_request(struct Curl_easy *data,
curlx_dyn_init(&canonical_query, CURL_MAX_HTTP_HEADER);
curlx_dyn_init(&canonical_path, CURL_MAX_HTTP_HEADER);
result = make_headers(data, hostname, timestamp,
result = make_headers(data, timestamp,
curlx_str(provider1), curlx_strlen(provider1),
date_header_out, content_sha256_hdr,
canonical_headers, signed_headers);
@ -1208,7 +1203,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data)
result = get_timestamp(timestamp, sizeof(timestamp));
if(!result)
result = make_canonical_request(data, hostname, timestamp,
result = make_canonical_request(data, timestamp,
&provider1, &service,
method, payload_hash, payload_hash_len,
&date_header, content_sha256_hdr,

View file

@ -125,12 +125,12 @@ static CURLcode decode_hex_key(struct Curl_easy *data,
}
/* @authority matches the Host header field-value when available (RFC 9421).
data->state.aptr.host is produced by http_set_aptr_host() before auth. */
data->state.http_host is produced by http_set_aptr_host() before auth. */
static CURLcode httpsig_authority(struct Curl_easy *data,
struct connectdata *conn,
struct dynbuf *authority_buf)
{
const char *h = data->state.aptr.host;
const char *h = data->state.http_host;
if(h && curl_strnequal(h, "host:", 5)) {
const char *value = h + 5;

View file

@ -132,7 +132,7 @@ static CURLcode dynhds_add_custom(struct Curl_easy *data,
/* trim surrounding whitespace so a padded field name (e.g.
`Authorization :`) cannot slip past the Authorization/Cookie check */
curlx_str_trimblanks(&name);
if(data->state.aptr.host &&
if(data->state.http_host &&
/* a Host: header was sent already, do not pass on any custom Host:
header as that will produce *two* in the same request! */
curlx_str_casecompare(&name, "Host"))

View file

@ -416,9 +416,9 @@ static CURLcode rtsp_setup_request(struct Curl_easy *data,
if(!Curl_checkheaders(data, STRCONST("Range")) && data->state.range) {
result = rtsp_header_alloc("Range",
data->state.range,
&data->state.aptr.rangeline);
&data->state.rangeline);
if(!result)
b->range = data->state.aptr.rangeline;
b->range = data->state.rangeline;
}
}
return result;

View file

@ -279,8 +279,10 @@ CURLcode Curl_close(struct Curl_easy **datap)
Curl_hash_destroy(&data->meta_hash);
Curl_creds_unlink(&data->state.creds);
curlx_safefree(data->state.aptr.rangeline);
curlx_safefree(data->state.aptr.host);
#ifndef CURL_DISABLE_HTTP
curlx_safefree(data->state.rangeline);
curlx_safefree(data->state.http_host);
#endif
#ifndef CURL_DISABLE_COOKIES
curlx_safefree(data->req.cookiehost);
#endif

View file

@ -609,13 +609,9 @@ struct UrlState {
struct Curl_creds *creds; /* Credentials for the origin only */
/* Dynamically allocated strings, MUST be freed before this struct is
killed. */
struct dynamically_allocated_data {
char *rangeline;
char *host;
} aptr;
#ifndef CURL_DISABLE_HTTP
char *rangeline; /* allocated */
char *http_host; /* allocated */
struct http_negotiation http_neg;
#endif
#ifndef CURL_DISABLE_RTSP