/* 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,
*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;
test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \
test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \
test1955 test1956 test1957 test1958 test1959 test1960 test1964 \
-test1970 test1971 test1972 test1973 test1974 test1975 \
+test1970 test1971 test1972 test1973 test1974 test1975 test1976 \
\
test2000 test2001 test2002 test2003 test2004 \
\
--- /dev/null
+<testcase>
+<info>
+<keywords>
+HTTP
+CURLOPT_AWS_SIGV4
+</keywords>
+</info>
+
+# Server-side
+<reply>
+<data>
+HTTP/1.1 200 OK
+Date: Thu, 09 Nov 2010 14:49:00 GMT
+Server: test-server/fake
+Content-Length: 0
+
+</data>
+</reply>
+
+# Client-side
+<client>
+<server>
+http
+</server>
+<features>
+SSL
+Debug
+crypto
+</features>
+<name>
+HTTP AWS_SIGV4 canonical request header sorting test
+</name>
+<command>
+-X PUT -H "X-Amz-Meta-Test-Two: test2" -H "x-amz-meta-test: test" --aws-sigv4 "aws:amz:us-east-1:s3" -u "xxx:yyy" http://%HOSTIP:%HTTPPORT/%TESTNUMBER
+</command>
+</client>
+
+# Verify data after the test has been "shot"
+<verify>
+<strip>
+^User-Agent:.*
+^Content-Length:.*
+^Accept:.*
+</strip>
+<strippart>
+# Strip the actual signature. We only care about header order in this test
+s/Signature=[a-f0-9]{64}/Signature=stripped/
+</strippart>
+<protocol crlf="yes">
+PUT /%TESTNUMBER HTTP/1.1
+Host: %HOSTIP:%HTTPPORT
+Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date;x-amz-meta-test;x-amz-meta-test-two, Signature=stripped
+X-Amz-Date: 19700101T000000Z
+x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
+X-Amz-Meta-Test-Two: test2
+x-amz-meta-test: test
+
+</protocol>
+</verify>
+</testcase>