import { createChecksumStream } from "@smithy/util-stream"; import { ChecksumAlgorithm } from "./constants"; import { getChecksum } from "./getChecksum"; import { getChecksumAlgorithmListForResponse } from "./getChecksumAlgorithmListForResponse"; import { getChecksumLocationName } from "./getChecksumLocationName"; import { isStreaming } from "./isStreaming"; import { selectChecksumAlgorithmFunction } from "./selectChecksumAlgorithmFunction"; export const validateChecksumFromResponse = async (response, { config, responseAlgorithms, logger }) => { const checksumAlgorithms = getChecksumAlgorithmListForResponse(responseAlgorithms); const { body: responseBody, headers: responseHeaders } = response; for (const algorithm of checksumAlgorithms) { const responseHeader = getChecksumLocationName(algorithm); const checksumFromResponse = responseHeaders[responseHeader]; if (checksumFromResponse) { let checksumAlgorithmFn; try { checksumAlgorithmFn = selectChecksumAlgorithmFunction(algorithm, config); } catch (error) { if (algorithm === ChecksumAlgorithm.CRC64NVME) { logger?.warn(`Skipping ${ChecksumAlgorithm.CRC64NVME} checksum validation: ${error.message}`); continue; } throw error; } const { base64Encoder } = config; if (isStreaming(responseBody)) { response.body = createChecksumStream({ expectedChecksum: checksumFromResponse, checksumSourceLocation: responseHeader, checksum: new checksumAlgorithmFn(), source: responseBody, base64Encoder, }); return; } const checksum = await getChecksum(responseBody, { checksumAlgorithmFn, base64Encoder }); if (checksum === checksumFromResponse) { break; } throw new Error(`Checksum mismatch: expected "${checksum}" but received "${checksumFromResponse}"` + ` in response header "${responseHeader}".`); } } };