in src/Signer/SignerV4.php [247:316]
private function calcCanonicalRequest(SigningContext $signingCtx, array $additionalHeaders): string
{
$request = $signingCtx->request;
// Canonical Request
// HTTP Verb + "\n" +
// Canonical URI + "\n" +
// Canonical Query String + "\n" +
// Canonical Headers + "\n" +
// Additional Headers + "\n" +
// Hashed PayLoad
// Canonical Uri
$uri = "/";
if (isset($signingCtx->bucket)) {
$uri .= $signingCtx->bucket . "/";
}
if (isset($signingCtx->key)) {
$uri .= $signingCtx->key;
}
$canonicalUri = str_replace(array('%2F'), array('/'), rawurlencode($uri));
// Canonical Query
$query = Query::parse($request->getUri()->getQuery(), false);
ksort($query);
$canonicalQuery = '';
foreach ($query as $k => $v) {
if (!empty($canonicalQuery)) {
$canonicalQuery .= '&';
}
$canonicalQuery .= $k;
if ($v != '') {
$canonicalQuery .= '=' . $v;
}
}
// Canonical Headers
$headers = [];
$addHeadersMap = array_map('strtolower', $additionalHeaders);
foreach (array_keys($request->getHeaders()) as $k) {
$lowk = strtolower((string)$k);
if ($this->isSignedHeader($lowk)) {
$headers[] = $lowk;
} elseif (in_array($lowk, $addHeadersMap, true)) {
$headers[] = $lowk;
}
}
sort($headers);
$canonicalHeaders = '';
foreach ($headers as $k) {
$headerValues = array_map('trim', $request->getHeader($k));
$canonicalHeaders .= $k . ':' . implode(',', $headerValues) . "\n";
}
// Additional Headers
$canonicalAdditionalHeaders = implode(';', $additionalHeaders);
// Assuming unsignedPayload is defined somewhere in the class
$hashPayload = self::UNSIGNED_PAYLOAD;
if (!empty($request->getHeaderLine(self::CONTENT_SHA256_HEADER))) {
$hashPayload = $request->getHeaderLine(self::CONTENT_SHA256_HEADER);
}
// Build Canonical Request
$canonicalRequest =
$request->getMethod() . "\n" .
$canonicalUri . "\n" .
$canonicalQuery . "\n" .
$canonicalHeaders . "\n" .
$canonicalAdditionalHeaders . "\n" .
$hashPayload;
return $canonicalRequest;
}