http_aws_sigv4: handle no-value user header entries

- Handle user headers in format 'name:' and 'name;' with no value.

The former is used when the user wants to remove an internal libcurl
header and the latter is used when the user actually wants to send a
no-value header in the format 'name:' (note the semi-colon is converted
by libcurl to a colon).

Prior to this change the AWS header import code did not special case
either of those and the generated AWS SignedHeaders would be incorrect.

Reported-by: apparentorder@users.noreply.github.com

Ref: https://curl.se/docs/manpage.html#-H

Fixes https://github.com/curl/curl/issues/11664
Closes https://github.com/curl/curl/pull/11668
This commit is contained in:
Jay Satiro 2023-08-12 15:06:08 -04:00
parent 14108c1b80
commit b5c65f8b7b
3 changed files with 51 additions and 5 deletions

View file

@ -199,10 +199,41 @@ static CURLcode make_headers(struct Curl_easy *data,
head = tmp_head;
}
/* copy user headers to our header list. the logic is based on how http.c
handles user headers.
user headers in format 'name:' with no value are used to signal that an
internal header of that name should be removed. those user headers are not
added to this list.
user headers in format 'name;' with no value are used to signal that a
header of that name with no value should be sent. those user headers are
added to this list but in the format that they will be sent, ie the
semi-colon is changed to a colon for format 'name:'.
user headers with a value of whitespace only, or without a colon or
semi-colon, are not added to this list.
*/
for(l = data->set.headers; l; l = l->next) {
tmp_head = curl_slist_append(head, l->data);
if(!tmp_head)
char *dupdata, *ptr;
char *sep = strchr(l->data, ':');
if(!sep)
sep = strchr(l->data, ';');
if(!sep || (*sep == ':' && !*(sep + 1)))
continue;
for(ptr = sep + 1; ISSPACE(*ptr); ++ptr)
;
if(!*ptr && ptr != sep + 1) /* a value of whitespace only */
continue;
dupdata = strdup(l->data);
if(!dupdata)
goto fail;
dupdata[sep - l->data] = ':';
tmp_head = Curl_slist_append_nodup(head, dupdata);
if(!tmp_head) {
free(dupdata);
goto fail;
}
head = tmp_head;
}