mirror of
https://github.com/curl/curl.git
synced 2026-08-26 10:43:32 +03:00
aws_sigv4: fix canon order for headers with same prefix
If a request containing two headers that have equivalent prefixes (ex. "x-amz-meta-test:test" and "x-amz-meta-test-two:test2") AWS expects the header with the shorter name to come first. The previous implementation used `strcmp` on the full header. Using the example, this would result in a comparison between the ':' and '-' chars and sort "x-amz-meta-test-two" before "x-amz-meta-test", which produces a different "StringToSign" than the one calculated by AWS. Test 1976 verifies Closes #14370
This commit is contained in:
parent
f3e07e5c55
commit
cf3e3d93d1
3 changed files with 94 additions and 3 deletions
|
|
@ -129,6 +129,37 @@ static void trim_headers(struct curl_slist *head)
|
|||
/* string been x-PROVIDER-date:TIMESTAMP, I need +1 for ':' */
|
||||
#define DATE_FULL_HDR_LEN (DATE_HDR_KEY_LEN + TIMESTAMP_SIZE + 1)
|
||||
|
||||
/* alphabetically compare two headers by their name, expecting
|
||||
headers to use ':' at this point */
|
||||
static int compare_header_names(const char *a, const char *b)
|
||||
{
|
||||
const char *colon_a;
|
||||
const char *colon_b;
|
||||
size_t len_a;
|
||||
size_t len_b;
|
||||
size_t min_len;
|
||||
int cmp;
|
||||
|
||||
colon_a = strchr(a, ':');
|
||||
colon_b = strchr(b, ':');
|
||||
|
||||
DEBUGASSERT(colon_a);
|
||||
DEBUGASSERT(colon_b);
|
||||
|
||||
len_a = colon_a ? (size_t)(colon_a - a) : strlen(a);
|
||||
len_b = colon_b ? (size_t)(colon_b - b) : strlen(b);
|
||||
|
||||
min_len = (len_a < len_b) ? len_a : len_b;
|
||||
|
||||
cmp = strncmp(a, b, min_len);
|
||||
|
||||
/* return the shorter of the two if one is shorter */
|
||||
if(!cmp)
|
||||
return (int)(len_a - len_b);
|
||||
|
||||
return cmp;
|
||||
}
|
||||
|
||||
/* timestamp should point to a buffer of at last TIMESTAMP_SIZE bytes */
|
||||
static CURLcode make_headers(struct Curl_easy *data,
|
||||
const char *hostname,
|
||||
|
|
@ -267,13 +298,13 @@ static CURLcode make_headers(struct Curl_easy *data,
|
|||
*date_header = NULL;
|
||||
}
|
||||
|
||||
/* alpha-sort in a case sensitive manner */
|
||||
/* alpha-sort by header name in a case sensitive manner */
|
||||
do {
|
||||
again = 0;
|
||||
for(l = head; l; l = l->next) {
|
||||
struct curl_slist *next = l->next;
|
||||
|
||||
if(next && strcmp(l->data, next->data) > 0) {
|
||||
if(next && compare_header_names(l->data, next->data) > 0) {
|
||||
char *tmp = l->data;
|
||||
|
||||
l->data = next->data;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue