The AWS documentation here seems to have somewhat confusing, incomplete or contradictory information. It states that
CanonicalHeaders is a list of request headers with their values.
Which suggests that we'd put all request headers in the canonical request. However, later, they state
The CanonicalHeaders list must include the following:
HTTP host header
If the Content-Type header is present in the request, it must be added to the CanonicalHeaders list.
Any x-amz-* headers that you plan to include in your request must also be added. For example, if you are using temporary security credentials, you will include x-amz-security-token in your request. You must add this header in the list of CanonicalHeaders.
OK, the bit about the Content-Type and x-amz headers suggests that we don't actually take all headers, because otherwise they wouldn't need to state that they'd be must be included. So then perhaps, we only need to take the Host
header, the Content-Type
header, and any x-amz-*
headers. But then below, it gets more confusing, because here's an example request:
GET /test.txt HTTP/1.1
Host: examplebucket.s3.amazonaws.com
Date: Fri, 24 May 2013 00:00:00 GMT
Authorization: SignatureToBeCalculated
Range: bytes=0-9
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date: 20130524T000000Z
And here's the example canonical request created from it:
GET
/test.txt
host:examplebucket.s3.amazonaws.com
range:bytes=0-9
x-amz-content-sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
x-amz-date:20130524T000000Z
host;range;x-amz-content-sha256;x-amz-date
e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
But this is inconsistent with both of the interpretations earlier: if we're supposed to only have Content-Type
, Host
and x-amz-*
headers, then what is the range
header doing in the list? And if we're just supposed to take all of the headers, then why isn't the Date
header in the list?
Is the list of headers to put in a canonical request then arbitrary, as long as it contains at least the minimum headers? What, exactly, is the definitive set of rules to construct the canonical request headers?