diff --git a/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.spec.ts b/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.spec.ts index 46aa6c395cb4..2371740b96c7 100644 --- a/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.spec.ts +++ b/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.spec.ts @@ -24,69 +24,6 @@ describe(flexibleChecksumsInputMiddleware.name, () => { vi.clearAllMocks(); }); - describe("sets input.requestAlgorithmMember", () => { - describe("input[requestAlgorithmMember] is not defined and", () => { - const mockMiddlewareConfigWithRequestAlgorithmMember = { - ...mockMiddlewareConfig, - requestAlgorithmMember: mockRequestAlgorithmMember, - }; - - it("requestChecksumCalculation is supported", async () => { - const handler = flexibleChecksumsInputMiddleware(mockConfig, mockMiddlewareConfigWithRequestAlgorithmMember)( - mockNext, - {} - ); - await handler({ input: {} }); - expect(mockNext).toHaveBeenCalledWith({ input: { [mockRequestAlgorithmMember]: DEFAULT_CHECKSUM_ALGORITHM } }); - }); - - it("requestChecksumRequired is set to true", async () => { - const mockConfigWithReqChecksumCalculationWhenRequired = { - ...mockConfig, - requestChecksumCalculation: () => Promise.resolve(RequestChecksumCalculation.WHEN_REQUIRED), - }; - - const handler = flexibleChecksumsInputMiddleware(mockConfigWithReqChecksumCalculationWhenRequired, { - ...mockMiddlewareConfigWithRequestAlgorithmMember, - requestChecksumRequired: true, - })(mockNext, {}); - - await handler({ input: {} }); - expect(mockNext).toHaveBeenCalledWith({ input: { [mockRequestAlgorithmMember]: DEFAULT_CHECKSUM_ALGORITHM } }); - }); - }); - }); - - describe("leaves input.requestAlgorithmMember", () => { - const mockMiddlewareConfigWithRequestAlgorithmMember = { - ...mockMiddlewareConfig, - requestAlgorithmMember: mockRequestAlgorithmMember, - }; - - it("when input[requestAlgorithmMember] is defined", async () => { - const handler = flexibleChecksumsInputMiddleware(mockConfig, mockMiddlewareConfigWithRequestAlgorithmMember)( - mockNext, - {} - ); - await handler({ input: { [mockRequestAlgorithmMember]: "SHA256" } }); - expect(mockNext).toHaveBeenCalledWith({ input: { [mockRequestAlgorithmMember]: "SHA256" } }); - }); - - it("if requestChecksumCalculation is required and requestChecksumRequired is false", async () => { - const mockConfigReqChecksumCalculationWhenRequired = { - ...mockConfig, - requestChecksumCalculation: () => Promise.resolve(RequestChecksumCalculation.WHEN_REQUIRED), - } as PreviouslyResolved; - - const handler = flexibleChecksumsInputMiddleware( - mockConfigReqChecksumCalculationWhenRequired, - mockMiddlewareConfigWithRequestAlgorithmMember - )(mockNext, {}); - await handler({ input: {} }); - expect(mockNext).toHaveBeenCalledWith({ input: {} }); - }); - }); - describe("sets input.requestValidationModeMember", () => { it("when requestValidationModeMember is defined and responseChecksumValidation is supported", async () => { const mockMiddlewareConfigWithMockRequestValidationModeMember = { diff --git a/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.ts b/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.ts index a3095f9fcad7..832fb8bbf060 100644 --- a/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.ts +++ b/packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.ts @@ -80,15 +80,6 @@ export const flexibleChecksumsInputMiddleware = break; } - // The value for input member to configure flexible checksum is not set. - if (requestAlgorithmMember && !input[requestAlgorithmMember]) { - // Set requestAlgorithmMember as default checksum algorithm only if request checksum calculation is supported - // or request checksum is required. - if (requestChecksumCalculation === RequestChecksumCalculation.WHEN_SUPPORTED || requestChecksumRequired) { - input[requestAlgorithmMember] = DEFAULT_CHECKSUM_ALGORITHM; - } - } - // The value for input member to opt-in to best-effort validation of a checksum returned in the HTTP response is not set. if (requestValidationModeMember && !input[requestValidationModeMember]) { // Set requestValidationModeMember as ENABLED only if response checksum validation is supported. diff --git a/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.spec.ts b/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.spec.ts index 337e597dc493..5156907134d1 100644 --- a/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.spec.ts +++ b/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.spec.ts @@ -29,12 +29,14 @@ describe(flexibleChecksumsMiddleware.name, () => { const mockChecksum = "mockChecksum"; const mockChecksumAlgorithmFunction = vi.fn(); const mockChecksumLocationName = "mock-checksum-location-name"; + const mockRequestAlgorithmMember = "mockRequestAlgorithmMember"; + const mockRequestAlgorithmMemberHttpHeader = "mock-request-algorithm-member-http-header"; const mockInput = {}; const mockConfig = { requestChecksumCalculation: () => Promise.resolve(RequestChecksumCalculation.WHEN_REQUIRED), } as PreviouslyResolved; - const mockMiddlewareConfig = { requestChecksumRequired: false }; + const mockMiddlewareConfig = { input: mockInput, requestChecksumRequired: false }; const mockBody = { body: "mockRequestBody" }; const mockHeaders = { "content-length": 100, "content-encoding": "gzip" }; @@ -78,66 +80,17 @@ describe(flexibleChecksumsMiddleware.name, () => { expect(getChecksumAlgorithmForRequest).toHaveBeenCalledTimes(1); }); - describe("skip if header is already present", async () => { - beforeEach(() => { - vi.mocked(hasHeaderWithPrefix).mockReturnValue(true); - }); - - afterEach(() => { - expect(hasHeaderWithPrefix).toHaveBeenCalledTimes(1); - expect(getChecksumLocationName).not.toHaveBeenCalled(); - expect(selectChecksumAlgorithmFunction).not.toHaveBeenCalled(); - expect(hasHeader).not.toHaveBeenCalled(); - }); - - it("with no changes input", async () => { - const handler = flexibleChecksumsMiddleware(mockConfig, mockMiddlewareConfig)(mockNext, {}); + it("skip if header is already present", async () => { + const handler = flexibleChecksumsMiddleware(mockConfig, mockMiddlewareConfig)(mockNext, {}); + vi.mocked(hasHeaderWithPrefix).mockReturnValue(true); - await handler(mockArgs); - expect(mockNext).toHaveBeenCalledWith(mockArgs); - }); + await handler(mockArgs); - describe("handles input[requestAlgorithmMember]", () => { - it("removes if respective checksum header is not present", async () => { - const mockRequestAlgorithmMember = "mockRequestAlgorithmMember"; - const handler = flexibleChecksumsMiddleware(mockConfig, { - ...mockMiddlewareConfig, - requestAlgorithmMember: mockRequestAlgorithmMember, - })(mockNext, {}); - - const mockArgsWithInput = { - ...mockArgs, - input: { [mockRequestAlgorithmMember]: DEFAULT_CHECKSUM_ALGORITHM }, - }; - await handler(mockArgsWithInput); - expect(mockNext).toHaveBeenCalledWith(mockArgs); - expect(mockNext.mock.calls[0][0].input[mockRequestAlgorithmMember]).toBeUndefined(); - }); - - // This means user set the checksum algorithm, as well as the actual checksum. - it("retains if respective checksum header is present", async () => { - const mockRequestAlgorithmMember = "mockRequestAlgorithmMember"; - const handler = flexibleChecksumsMiddleware(mockConfig, { - ...mockMiddlewareConfig, - requestAlgorithmMember: mockRequestAlgorithmMember, - })(mockNext, {}); - - const mockArgsWithInputAndRequest = { - ...mockArgs, - input: { [mockRequestAlgorithmMember]: DEFAULT_CHECKSUM_ALGORITHM }, - request: { - ...mockRequest, - headers: { - ...mockHeaders, - [`x-amz-checksum-${DEFAULT_CHECKSUM_ALGORITHM.toLowerCase()}`]: mockChecksum, - }, - }, - }; - await handler(mockArgsWithInputAndRequest); - expect(mockNext).toHaveBeenCalledWith(mockArgsWithInputAndRequest); - expect(mockNext.mock.calls[0][0].input[mockRequestAlgorithmMember]).toBe(DEFAULT_CHECKSUM_ALGORITHM); - }); - }); + expect(hasHeaderWithPrefix).toHaveBeenCalledTimes(1); + expect(getChecksumLocationName).not.toHaveBeenCalled(); + expect(selectChecksumAlgorithmFunction).not.toHaveBeenCalled(); + expect(hasHeader).not.toHaveBeenCalled(); + expect(mockNext).toHaveBeenCalledWith(mockArgs); }); }); }); @@ -151,6 +104,44 @@ describe(flexibleChecksumsMiddleware.name, () => { expect(selectChecksumAlgorithmFunction).toHaveBeenCalledTimes(1); }); + describe("if input.requestAlgorithmMember can be set", () => { + describe("input[requestAlgorithmMember] is not defined and", () => { + const mockMwConfigWithReqAlgoMember = { + ...mockMiddlewareConfig, + requestAlgorithmMember: mockRequestAlgorithmMember, + requestAlgorithmMemberHttpHeader: mockRequestAlgorithmMemberHttpHeader, + }; + + it("requestChecksumCalculation is supported", async () => { + const handler = flexibleChecksumsMiddleware( + { + ...mockConfig, + requestChecksumCalculation: () => Promise.resolve(RequestChecksumCalculation.WHEN_SUPPORTED), + }, + mockMwConfigWithReqAlgoMember + )(mockNext, {}); + await handler(mockArgs); + expect(mockNext.mock.calls[0][0].input[mockRequestAlgorithmMember]).toEqual(DEFAULT_CHECKSUM_ALGORITHM); + expect(mockNext.mock.calls[0][0].request.headers[mockRequestAlgorithmMemberHttpHeader]).toEqual( + DEFAULT_CHECKSUM_ALGORITHM + ); + }); + + it("requestChecksumRequired is set to true", async () => { + const handler = flexibleChecksumsMiddleware(mockConfig, { + ...mockMwConfigWithReqAlgoMember, + requestChecksumRequired: true, + })(mockNext, {}); + + await handler(mockArgs); + expect(mockNext.mock.calls[0][0].input[mockRequestAlgorithmMember]).toEqual(DEFAULT_CHECKSUM_ALGORITHM); + expect(mockNext.mock.calls[0][0].request.headers[mockRequestAlgorithmMemberHttpHeader]).toEqual( + DEFAULT_CHECKSUM_ALGORITHM + ); + }); + }); + }); + it("for streaming body", async () => { vi.mocked(isStreaming).mockReturnValue(true); const mockUpdatedBody = { body: "mockUpdatedBody" }; diff --git a/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.ts b/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.ts index 1197de9d25dc..3a196cad488c 100644 --- a/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.ts +++ b/packages/middleware-flexible-checksums/src/flexibleChecksumsMiddleware.ts @@ -11,7 +11,7 @@ import { } from "@smithy/types"; import { PreviouslyResolved } from "./configuration"; -import { ChecksumAlgorithm, DEFAULT_CHECKSUM_ALGORITHM } from "./constants"; +import { ChecksumAlgorithm, DEFAULT_CHECKSUM_ALGORITHM, RequestChecksumCalculation } from "./constants"; import { getChecksumAlgorithmForRequest } from "./getChecksumAlgorithmForRequest"; import { getChecksumLocationName } from "./getChecksumLocationName"; import { hasHeader } from "./hasHeader"; @@ -60,26 +60,28 @@ export const flexibleChecksumsMiddleware = return next(args); } - const { request, input } = args; - const { body: requestBody, headers } = request; - const { requestChecksumRequired, requestAlgorithmMember } = middlewareConfig; - - if (hasHeaderWithPrefix("x-amz-checksum-", headers)) { - // Remove input[requestAlgorithmMember] and header, if it was added by flexibleChecksumsInputMiddleware - if ( - requestAlgorithmMember && - input[requestAlgorithmMember] === DEFAULT_CHECKSUM_ALGORITHM && - !headers[`x-amz-checksum-${DEFAULT_CHECKSUM_ALGORITHM.toLowerCase()}`] - ) { - delete input[requestAlgorithmMember]; - delete headers["x-amz-sdk-checksum-algorithm"]; - } + if (hasHeaderWithPrefix("x-amz-checksum-", args.request.headers)) { return next(args); } + const { request, input } = args; + const { body: requestBody, headers } = request; const { base64Encoder, streamHasher } = config; + const { requestChecksumRequired, requestAlgorithmMember, requestAlgorithmMemberHttpHeader } = middlewareConfig; const requestChecksumCalculation = await config.requestChecksumCalculation(); + // The value for input member to configure flexible checksum is not set. + if (requestAlgorithmMember && !input[requestAlgorithmMember]) { + // Set requestAlgorithmMember as default checksum algorithm only if request checksum calculation is supported + // or request checksum is required. + if (requestChecksumCalculation === RequestChecksumCalculation.WHEN_SUPPORTED || requestChecksumRequired) { + input[requestAlgorithmMember] = DEFAULT_CHECKSUM_ALGORITHM; + if (requestAlgorithmMemberHttpHeader) { + headers[requestAlgorithmMemberHttpHeader] = DEFAULT_CHECKSUM_ALGORITHM; + } + } + } + const checksumAlgorithm = getChecksumAlgorithmForRequest(input, { requestChecksumRequired, requestAlgorithmMember,