"use strict"; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __hasOwnProp = Object.prototype.hasOwnProperty; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var src_exports = {}; __export(src_exports, { ChecksumAlgorithm: () => ChecksumAlgorithm, ChecksumLocation: () => ChecksumLocation, DEFAULT_CHECKSUM_ALGORITHM: () => DEFAULT_CHECKSUM_ALGORITHM, S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM: () => S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM, flexibleChecksumsMiddleware: () => flexibleChecksumsMiddleware, flexibleChecksumsMiddlewareOptions: () => flexibleChecksumsMiddlewareOptions, getFlexibleChecksumsPlugin: () => getFlexibleChecksumsPlugin }); module.exports = __toCommonJS(src_exports); // src/constants.ts var ChecksumAlgorithm = /* @__PURE__ */ ((ChecksumAlgorithm3) => { ChecksumAlgorithm3["MD5"] = "MD5"; ChecksumAlgorithm3["CRC32"] = "CRC32"; ChecksumAlgorithm3["CRC32C"] = "CRC32C"; ChecksumAlgorithm3["SHA1"] = "SHA1"; ChecksumAlgorithm3["SHA256"] = "SHA256"; return ChecksumAlgorithm3; })(ChecksumAlgorithm || {}); var ChecksumLocation = /* @__PURE__ */ ((ChecksumLocation2) => { ChecksumLocation2["HEADER"] = "header"; ChecksumLocation2["TRAILER"] = "trailer"; return ChecksumLocation2; })(ChecksumLocation || {}); var DEFAULT_CHECKSUM_ALGORITHM = "MD5" /* MD5 */; var S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM = "CRC32" /* CRC32 */; // src/flexibleChecksumsMiddleware.ts var import_protocol_http = require("@smithy/protocol-http"); // src/types.ts var CLIENT_SUPPORTED_ALGORITHMS = [ "CRC32" /* CRC32 */, "CRC32C" /* CRC32C */, "SHA1" /* SHA1 */, "SHA256" /* SHA256 */ ]; var PRIORITY_ORDER_ALGORITHMS = [ "CRC32" /* CRC32 */, "CRC32C" /* CRC32C */, "SHA1" /* SHA1 */, "SHA256" /* SHA256 */ ]; // src/getChecksumAlgorithmForRequest.ts var getChecksumAlgorithmForRequest = /* @__PURE__ */ __name((input, { requestChecksumRequired, requestAlgorithmMember }, isS3Express) => { const defaultAlgorithm = isS3Express ? S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM : DEFAULT_CHECKSUM_ALGORITHM; if (!requestAlgorithmMember || !input[requestAlgorithmMember]) { return requestChecksumRequired ? defaultAlgorithm : void 0; } const checksumAlgorithm = input[requestAlgorithmMember]; if (!CLIENT_SUPPORTED_ALGORITHMS.includes(checksumAlgorithm)) { throw new Error( `The checksum algorithm "${checksumAlgorithm}" is not supported by the client. Select one of ${CLIENT_SUPPORTED_ALGORITHMS}.` ); } return checksumAlgorithm; }, "getChecksumAlgorithmForRequest"); // src/getChecksumLocationName.ts var getChecksumLocationName = /* @__PURE__ */ __name((algorithm) => algorithm === "MD5" /* MD5 */ ? "content-md5" : `x-amz-checksum-${algorithm.toLowerCase()}`, "getChecksumLocationName"); // src/hasHeader.ts var hasHeader = /* @__PURE__ */ __name((header, headers) => { const soughtHeader = header.toLowerCase(); for (const headerName of Object.keys(headers)) { if (soughtHeader === headerName.toLowerCase()) { return true; } } return false; }, "hasHeader"); // src/isStreaming.ts var import_is_array_buffer = require("@smithy/is-array-buffer"); var isStreaming = /* @__PURE__ */ __name((body) => body !== void 0 && typeof body !== "string" && !ArrayBuffer.isView(body) && !(0, import_is_array_buffer.isArrayBuffer)(body), "isStreaming"); // src/selectChecksumAlgorithmFunction.ts var import_crc32 = require("@aws-crypto/crc32"); var import_crc32c = require("@aws-crypto/crc32c"); var selectChecksumAlgorithmFunction = /* @__PURE__ */ __name((checksumAlgorithm, config) => ({ ["MD5" /* MD5 */]: config.md5, ["CRC32" /* CRC32 */]: import_crc32.AwsCrc32, ["CRC32C" /* CRC32C */]: import_crc32c.AwsCrc32c, ["SHA1" /* SHA1 */]: config.sha1, ["SHA256" /* SHA256 */]: config.sha256 })[checksumAlgorithm], "selectChecksumAlgorithmFunction"); // src/stringHasher.ts var import_util_utf8 = require("@smithy/util-utf8"); var stringHasher = /* @__PURE__ */ __name((checksumAlgorithmFn, body) => { const hash = new checksumAlgorithmFn(); hash.update((0, import_util_utf8.toUint8Array)(body || "")); return hash.digest(); }, "stringHasher"); // src/flexibleChecksumsMiddleware.ts var flexibleChecksumsMiddlewareOptions = { name: "flexibleChecksumsMiddleware", step: "build", tags: ["BODY_CHECKSUM"], override: true }; var flexibleChecksumsMiddleware = /* @__PURE__ */ __name((config, middlewareConfig) => (next, context) => async (args) => { if (!import_protocol_http.HttpRequest.isInstance(args.request)) { return next(args); } const { request } = args; const { body: requestBody, headers } = request; const { base64Encoder, streamHasher } = config; const { input, requestChecksumRequired, requestAlgorithmMember } = middlewareConfig; const checksumAlgorithm = getChecksumAlgorithmForRequest( input, { requestChecksumRequired, requestAlgorithmMember }, !!context.isS3ExpressBucket ); let updatedBody = requestBody; let updatedHeaders = headers; if (checksumAlgorithm) { const checksumLocationName = getChecksumLocationName(checksumAlgorithm); const checksumAlgorithmFn = selectChecksumAlgorithmFunction(checksumAlgorithm, config); if (isStreaming(requestBody)) { const { getAwsChunkedEncodingStream, bodyLengthChecker } = config; updatedBody = getAwsChunkedEncodingStream(requestBody, { base64Encoder, bodyLengthChecker, checksumLocationName, checksumAlgorithmFn, streamHasher }); updatedHeaders = { ...headers, "content-encoding": headers["content-encoding"] ? `${headers["content-encoding"]},aws-chunked` : "aws-chunked", "transfer-encoding": "chunked", "x-amz-decoded-content-length": headers["content-length"], "x-amz-content-sha256": "STREAMING-UNSIGNED-PAYLOAD-TRAILER", "x-amz-trailer": checksumLocationName }; delete updatedHeaders["content-length"]; } else if (!hasHeader(checksumLocationName, headers)) { const rawChecksum = await stringHasher(checksumAlgorithmFn, requestBody); updatedHeaders = { ...headers, [checksumLocationName]: base64Encoder(rawChecksum) }; } } const result = await next({ ...args, request: { ...request, headers: updatedHeaders, body: updatedBody } }); return result; }, "flexibleChecksumsMiddleware"); // src/flexibleChecksumsResponseMiddleware.ts // src/getChecksumAlgorithmListForResponse.ts var getChecksumAlgorithmListForResponse = /* @__PURE__ */ __name((responseAlgorithms = []) => { const validChecksumAlgorithms = []; for (const algorithm of PRIORITY_ORDER_ALGORITHMS) { if (!responseAlgorithms.includes(algorithm) || !CLIENT_SUPPORTED_ALGORITHMS.includes(algorithm)) { continue; } validChecksumAlgorithms.push(algorithm); } return validChecksumAlgorithms; }, "getChecksumAlgorithmListForResponse"); // src/isChecksumWithPartNumber.ts var isChecksumWithPartNumber = /* @__PURE__ */ __name((checksum) => { const lastHyphenIndex = checksum.lastIndexOf("-"); if (lastHyphenIndex !== -1) { const numberPart = checksum.slice(lastHyphenIndex + 1); if (!numberPart.startsWith("0")) { const number = parseInt(numberPart, 10); if (!isNaN(number) && number >= 1 && number <= 1e4) { return true; } } } return false; }, "isChecksumWithPartNumber"); // src/flexibleChecksumsResponseMiddleware.ts var import_create_read_stream_on_buffer = require("./streams/create-read-stream-on-buffer"); // src/getChecksum.ts var getChecksum = /* @__PURE__ */ __name(async (body, { streamHasher, checksumAlgorithmFn, base64Encoder }) => { const digest = isStreaming(body) ? streamHasher(checksumAlgorithmFn, body) : stringHasher(checksumAlgorithmFn, body); return base64Encoder(await digest); }, "getChecksum"); // src/validateChecksumFromResponse.ts var validateChecksumFromResponse = /* @__PURE__ */ __name(async (response, { config, responseAlgorithms }) => { 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) { const checksumAlgorithmFn = selectChecksumAlgorithmFunction(algorithm, config); const { streamHasher, base64Encoder } = config; const checksum = await getChecksum(responseBody, { streamHasher, checksumAlgorithmFn, base64Encoder }); if (checksum === checksumFromResponse) { break; } throw new Error( `Checksum mismatch: expected "${checksum}" but received "${checksumFromResponse}" in response header "${responseHeader}".` ); } } }, "validateChecksumFromResponse"); // src/flexibleChecksumsResponseMiddleware.ts var flexibleChecksumsResponseMiddlewareOptions = { name: "flexibleChecksumsResponseMiddleware", toMiddleware: "deserializerMiddleware", relation: "after", tags: ["BODY_CHECKSUM"], override: true }; var flexibleChecksumsResponseMiddleware = /* @__PURE__ */ __name((config, middlewareConfig) => (next, context) => async (args) => { if (!import_protocol_http.HttpRequest.isInstance(args.request)) { return next(args); } const input = args.input; const result = await next(args); const response = result.response; let collectedStream = void 0; const { requestValidationModeMember, responseAlgorithms } = middlewareConfig; if (requestValidationModeMember && input[requestValidationModeMember] === "ENABLED") { const { clientName, commandName } = context; const isS3WholeObjectMultipartGetResponseChecksum = clientName === "S3Client" && commandName === "GetObjectCommand" && getChecksumAlgorithmListForResponse(responseAlgorithms).every((algorithm) => { const responseHeader = getChecksumLocationName(algorithm); const checksumFromResponse = response.headers[responseHeader]; return !checksumFromResponse || isChecksumWithPartNumber(checksumFromResponse); }); if (isS3WholeObjectMultipartGetResponseChecksum) { return result; } const isStreamingBody = isStreaming(response.body); if (isStreamingBody) { collectedStream = await config.streamCollector(response.body); response.body = (0, import_create_read_stream_on_buffer.createReadStreamOnBuffer)(collectedStream); } await validateChecksumFromResponse(result.response, { config, responseAlgorithms }); if (isStreamingBody && collectedStream) { response.body = (0, import_create_read_stream_on_buffer.createReadStreamOnBuffer)(collectedStream); } } return result; }, "flexibleChecksumsResponseMiddleware"); // src/getFlexibleChecksumsPlugin.ts var getFlexibleChecksumsPlugin = /* @__PURE__ */ __name((config, middlewareConfig) => ({ applyToStack: (clientStack) => { clientStack.add(flexibleChecksumsMiddleware(config, middlewareConfig), flexibleChecksumsMiddlewareOptions); clientStack.addRelativeTo( flexibleChecksumsResponseMiddleware(config, middlewareConfig), flexibleChecksumsResponseMiddlewareOptions ); } }), "getFlexibleChecksumsPlugin"); // Annotate the CommonJS export names for ESM import in node: 0 && (module.exports = { ChecksumAlgorithm, ChecksumLocation, DEFAULT_CHECKSUM_ALGORITHM, S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM, flexibleChecksumsMiddlewareOptions, flexibleChecksumsMiddleware, getFlexibleChecksumsPlugin });