Creating a Canonical Request
You can standardize the information of your request in a canonical format.
You need to use a canonical format for your request because 3DS OUTSCALE uses the same format to recalculate your signature when you send your request.
Once the canonical request is hashed, you need to add it to the string to sign that you create in Creating a String to Sign.
You do not need to do this procedure if you use AWS CLI or an SDK for your API request.
Specify the HTTP request method (
POST) following this syntax (where \n is a newline character):Example of request method
Add the canonical URI following this syntax (where \n is a newline character):Example of canonical URI with encoding
The canonical URI is the URI-encoded version of the URI absolute path. This corresponds to everything between the HTTP host and the question mark character ("?") which begins the query string parameters.
You must normalize URI paths according to the RFC 3986. Therefore, you must remove all redundant and relative path components.
If the absolute path is empty, use a slash (/):Example of canonical URI
Add the canonical query string following this syntax (where \n is a newline character):Example of canonical query string
To build this canonical query string:
Sort the names of the parameters by character code point, in ascending order.
URI-encode each parameter name and value according to the following rules:
Do not URI-encode the authorized characters defined in the RFC 3986: a-z, A-Z, 0-9 et -_.~
Percent-encode all the other characters: %XY, where X and Y are hexadecimal characters (0 to 9 and A to F). For example, the space character must be encoded %20.
Build the canonical query string starting with the name of the first parameter in the sorted list.
For each parameter, append the URI-encoded parameter name, followed by the equal sign (=), followed by the value of the URI-encoded parameter. For parameters with no value, use an empty string.
Append the ampersand character (&) after each parameter value, except for the last value of the list.
If the request does not contain a query string, use an empty string.
Add the canonical headers following this syntax (where \n is a newline character):Example of signed headers
content-type:application/x-www-form-urlencoded; charset=utf-8\n host:fcu.eu-west-2.outscale.com\n x-amz-date:20180915T163400Z\n
The canonical headers correspond to the list of all the HTTP headers contained in the signed request.
hostheader is mandatory. Other standard headers such as
To build the list of canonical headers, refer to the following pseudocode:Example of signed headers
CanonicalHeaders = CanonicalHeadersEntry0 + CanonicalHeadersEntry1 + ... + CanonicalHeadersEntryN CanonicalHeadersEntry = Lowercase(HeaderName) + ':' + Trimall(HeaderValue) + '\n'
Lowercasefunction converts all characters to lowercase. The
Trimallfunction removes extra spaces before and after values, and converts sequential spaces into single spaces.
Build the list of canonical headers by sorting the headers by character code, and then by iterating through their names.
Build each header according to the following rules:
Example of original headers
Append the header name in lowercase, followed by a colon (":")
Append the list of values separated by semicolons (";") for that header. Do not sort values in the headers that have several values.
Append a new line character (\n)
Host:fcu.eu-west-2.outscale.com\n Content-Type:application/x-www-form-urlencoded; charset=utf-8\n My-header1: a b c \n X-Amz-Date:20180915T163400Z\n My-Header2: "a b c" \nExample of headers in canonical format
content-type:application/x-www-form-urlencoded; charset=utf-8\n host:fcu.eu-west-2.outscale.com\n my-header1:a b c\n my-header2:"a b c"\n x-amz-date:20180915T163400Z\n
Add the signed headers following this syntax (where \n is a newline character):Example of signed headers
Signed headers correspond to the list of headers you included in the canonical headers.
hostheader is a mandatory signed header. If you want to add a date or an
x-amz-dateheader, you must also include this header in the list of signed headers.
To build the list of signed headers, refer to the following pseudocode:Example of signed headers
SignedHeaders = Lowercase(HeaderName0) + ';' + Lowercase(HeaderName1) + ";" + ... + Lowercase(HeaderNameN)
Convert all header names into lowercases with the
Lowercasefunction, sort them by character code and use a semicolon (";") to separate header names.
Use a hash function to create a hash value from the payload in the body of the HTTP request.Sample of structure of a payload
HashedPayload = Lowercase(HexEncode(Hash(requestPayload)))
The hashed payload must be a lowercase hexadecimal string.
If the payload is empty, use an empty string for the hash function. In our example, the payload is empty.
The payload is hashed.Example of hashed payload (empty string)
To build the canonical request, combine all the elements from the previous steps:Example of canonical request
GET / Action=DescribeInstances&Version=2016-09-15 content-type:application/x-www-form-urlencoded; charset=utf-8 host:fcu.eu-west-2.outscale.com x-amz-date:20180915T163400Z content-type;host;x-amz-date ae14e49469bac4395994faf4b0b3e9824c41b724914c1fc98c69585b2729fb58
Hash the canonical request with the same algorithm you used to hash the payload.Example of hashed canonical request
The canonical request is hashed. You then need to add it to the string to sign that you create in Creating a String to Sign.
AWS™ and Amazon Web Services™ are trademarks of Amazon Technologies, Inc or its affiliates in the United States and/or other countries.