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;
}
<protocol>
GET /aws_sigv4/testapi/test HTTP/1.1\r
Host: exam.ple.com:9000\r
-Authorization: XXX4-HMAC-SHA256 Credential=xxx/19700101/ple/exam/xxx4_request, SignedHeaders=content-type;host;tesmixcase;test0;test1;test2;test_space;x-xxx-date, Signature=779a8ff876528aece8bf03b1296702af0644a4745aa5feabb6ebb1a7bb0d907e\r
+Authorization: XXX4-HMAC-SHA256 Credential=xxx/19700101/ple/exam/xxx4_request, SignedHeaders=content-type;host;tesmixcase;test2;test3;test_space;x-xxx-date, Signature=dd39202e9fb7b836ebf2abb83b114cae11ff3b6a169f0c64b290a774a873db9d\r
X-Xxx-Date: 19700101T000000Z\r
-test2: 1234\r
+test3: 1234\r
+test2:\r
test_space: t s m end \r
tesMixCase: MixCase\r
\r
test_setopt(curl, CURLOPT_USERPWD, "xxx");
test_setopt(curl, CURLOPT_HEADER, 0L);
test_setopt(curl, CURLOPT_URL, URL);
- list = curl_slist_append(list, "test2: 1234");
+ list = curl_slist_append(list, "test3: 1234");
if(!list)
goto test_cleanup;
if(libtest_arg2) {
}
test_setopt(curl, CURLOPT_CONNECT_TO, connect_to);
curl_slist_append(list, "Content-Type: application/json");
+
+ /* 'name;' user headers with no value are used to send an empty header in the
+ format 'name:' (note the semi-colon becomes a colon). this entry should
+ show in SignedHeaders without an additional semi-colon, as any other
+ header would. eg 'foo;test2;test3' and not 'foo;test2;;test3'. */
+ curl_slist_append(list, "test2;");
+
+ /* 'name:' user headers with no value are used to signal an internal header
+ of that name should be removed and are not sent as a header. this entry
+ should not show in SignedHeaders. */
curl_slist_append(list, "test1:");
+
+ /* 'name' user headers with no separator or value are invalid and ignored.
+ this entry should not show in SignedHeaders. */
curl_slist_append(list, "test0");
+
curl_slist_append(list, "test_space: t\ts m\t end ");
curl_slist_append(list, "tesMixCase: MixCase");
test_setopt(curl, CURLOPT_HTTPHEADER, list);