Skip to content

Commit c9014bf

Browse files
committed
chore(middleware-flexible-checksums): use ResponseChecksumValidation
1 parent 0f2862f commit c9014bf

File tree

3 files changed

+51
-8
lines changed

3 files changed

+51
-8
lines changed

packages/middleware-flexible-checksums/src/configuration.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ export interface PreviouslyResolved {
3737
*/
3838
requestChecksumCalculation: Provider<string>;
3939

40+
/**
41+
* Determines when a checksum will be calculated for response payloads
42+
*/
43+
responseChecksumValidation: Provider<string>;
44+
4045
/**
4146
* A constructor for a class implementing the {@link Hash} interface that computes SHA1 hashes.
4247
* @internal

packages/middleware-flexible-checksums/src/flexibleChecksumsResponseMiddleware.spec.ts

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { HttpRequest } from "@smithy/protocol-http";
22
import { DeserializeHandlerArguments } from "@smithy/types";
33

44
import { PreviouslyResolved } from "./configuration";
5-
import { ChecksumAlgorithm } from "./constants";
5+
import { ChecksumAlgorithm, ResponseChecksumValidation } from "./constants";
66
import { flexibleChecksumsResponseMiddleware } from "./flexibleChecksumsResponseMiddleware";
77
import { getChecksumLocationName } from "./getChecksumLocationName";
88
import { FlexibleChecksumsMiddlewareConfig } from "./getFlexibleChecksumsPlugin";
@@ -23,7 +23,9 @@ describe(flexibleChecksumsResponseMiddleware.name, () => {
2323
commandName: "mockCommandName",
2424
};
2525

26-
const mockConfig = {} as PreviouslyResolved;
26+
const mockConfig = {
27+
responseChecksumValidation: () => Promise.resolve(ResponseChecksumValidation.WHEN_REQUIRED),
28+
} as PreviouslyResolved;
2729
const mockRequestValidationModeMember = "ChecksumEnabled";
2830
const mockResponseAlgorithms = [ChecksumAlgorithm.CRC32, ChecksumAlgorithm.CRC32C];
2931
const mockMiddlewareConfig = {
@@ -65,6 +67,7 @@ describe(flexibleChecksumsResponseMiddleware.name, () => {
6567
const handler = flexibleChecksumsResponseMiddleware(mockConfig, mockMiddlewareConfig)(mockNext, mockContext);
6668
await handler(mockArgs);
6769
expect(validateChecksumFromResponse).not.toHaveBeenCalled();
70+
expect(mockNext).toHaveBeenCalledWith(mockArgs);
6871
});
6972

7073
describe("response checksum", () => {
@@ -74,12 +77,16 @@ describe(flexibleChecksumsResponseMiddleware.name, () => {
7477
const handler = flexibleChecksumsResponseMiddleware(mockConfig, mockMwConfig)(mockNext, mockContext);
7578
await handler(mockArgs);
7679
expect(validateChecksumFromResponse).not.toHaveBeenCalled();
80+
expect(mockNext).toHaveBeenCalledWith(mockArgs);
7781
});
7882

7983
it("if requestValidationModeMember is not enabled in input", async () => {
8084
const handler = flexibleChecksumsResponseMiddleware(mockConfig, mockMiddlewareConfig)(mockNext, mockContext);
81-
await handler({ ...mockArgs, input: {} });
85+
86+
const mockArgsWithoutEnabled = { ...mockArgs, input: {} };
87+
await handler(mockArgsWithoutEnabled);
8288
expect(validateChecksumFromResponse).not.toHaveBeenCalled();
89+
expect(mockNext).toHaveBeenCalledWith(mockArgsWithoutEnabled);
8390
});
8491

8592
it("if checksum is for S3 whole-object multipart GET", async () => {
@@ -92,19 +99,39 @@ describe(flexibleChecksumsResponseMiddleware.name, () => {
9299
expect(isChecksumWithPartNumber).toHaveBeenCalledTimes(1);
93100
expect(isChecksumWithPartNumber).toHaveBeenCalledWith(mockChecksum);
94101
expect(validateChecksumFromResponse).not.toHaveBeenCalled();
102+
expect(mockNext).toHaveBeenCalledWith(mockArgs);
95103
});
96104
});
97105
});
98106

99107
describe("validates checksum from response header", () => {
100-
it("generic case", async () => {
108+
it("if requestValidationModeMember is enabled in input", async () => {
101109
const handler = flexibleChecksumsResponseMiddleware(mockConfig, mockMiddlewareConfig)(mockNext, mockContext);
102110

103111
await handler(mockArgs);
104112
expect(validateChecksumFromResponse).toHaveBeenCalledWith(mockResult.response, {
105113
config: mockConfig,
106114
responseAlgorithms: mockResponseAlgorithms,
107115
});
116+
expect(mockNext).toHaveBeenCalledWith(mockArgs);
117+
});
118+
119+
it(`if requestValidationModeMember is not enabled in input, but responseChecksumValidation returns ${ResponseChecksumValidation.WHEN_SUPPORTED}`, async () => {
120+
const mockConfigWithResponseChecksumValidationSupported = {
121+
...mockConfig,
122+
responseChecksumValidation: () => Promise.resolve(ResponseChecksumValidation.WHEN_SUPPORTED),
123+
};
124+
const handler = flexibleChecksumsResponseMiddleware(
125+
mockConfigWithResponseChecksumValidationSupported,
126+
mockMiddlewareConfig
127+
)(mockNext, mockContext);
128+
129+
await handler({ ...mockArgs, input: {} });
130+
expect(validateChecksumFromResponse).toHaveBeenCalledWith(mockResult.response, {
131+
config: mockConfigWithResponseChecksumValidationSupported,
132+
responseAlgorithms: mockResponseAlgorithms,
133+
});
134+
expect(mockNext).toHaveBeenCalledWith(mockArgs);
108135
});
109136

110137
it("if checksum is for S3 GET without part number", async () => {
@@ -120,6 +147,7 @@ describe(flexibleChecksumsResponseMiddleware.name, () => {
120147
config: mockConfig,
121148
responseAlgorithms: mockResponseAlgorithms,
122149
});
150+
expect(mockNext).toHaveBeenCalledWith(mockArgs);
123151
});
124152
});
125153
});

packages/middleware-flexible-checksums/src/flexibleChecksumsResponseMiddleware.ts

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import {
1010
} from "@smithy/types";
1111

1212
import { PreviouslyResolved } from "./configuration";
13-
import { ChecksumAlgorithm } from "./constants";
13+
import { ChecksumAlgorithm, ResponseChecksumValidation } from "./constants";
1414
import { getChecksumAlgorithmListForResponse } from "./getChecksumAlgorithmListForResponse";
1515
import { getChecksumLocationName } from "./getChecksumLocationName";
1616
import { isChecksumWithPartNumber } from "./isChecksumWithPartNumber";
@@ -63,14 +63,24 @@ export const flexibleChecksumsResponseMiddleware =
6363
}
6464

6565
const input = args.input;
66+
const { requestValidationModeMember, responseAlgorithms } = middlewareConfig;
67+
const responseChecksumValidation = await config.responseChecksumValidation();
68+
69+
const isResponseChecksumValidationNeeded =
70+
requestValidationModeMember &&
71+
(input[requestValidationModeMember] === "ENABLED" ||
72+
responseChecksumValidation === ResponseChecksumValidation.WHEN_SUPPORTED);
73+
74+
if (isResponseChecksumValidationNeeded) {
75+
input[requestValidationModeMember] = "ENABLED";
76+
}
77+
6678
const result = await next(args);
6779

6880
const response = result.response as HttpResponse;
6981
let collectedStream: Uint8Array | undefined = undefined;
7082

71-
const { requestValidationModeMember, responseAlgorithms } = middlewareConfig;
72-
// @ts-ignore Element implicitly has an 'any' type for input[requestValidationModeMember]
73-
if (requestValidationModeMember && input[requestValidationModeMember] === "ENABLED") {
83+
if (isResponseChecksumValidationNeeded) {
7484
const { clientName, commandName } = context;
7585
const isS3WholeObjectMultipartGetResponseChecksum =
7686
clientName === "S3Client" &&

0 commit comments

Comments
 (0)