forked from aws/aws-sdk-js-v3
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
chore(middleware-flexible-checksums): perform checksum calculation an…
…d validation by default (aws#6750)
- Loading branch information
Showing
9 changed files
with
478 additions
and
135 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
103 changes: 103 additions & 0 deletions
103
packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,103 @@ | ||
import { setFeature } from "@aws-sdk/core"; | ||
import { afterEach, describe, expect, test as it, vi } from "vitest"; | ||
|
||
import { PreviouslyResolved } from "./configuration"; | ||
import { DEFAULT_CHECKSUM_ALGORITHM, RequestChecksumCalculation, ResponseChecksumValidation } from "./constants"; | ||
import { flexibleChecksumsInputMiddleware } from "./flexibleChecksumsInputMiddleware"; | ||
|
||
vi.mock("@aws-sdk/core"); | ||
|
||
describe(flexibleChecksumsInputMiddleware.name, () => { | ||
const mockNext = vi.fn(); | ||
const mockRequestValidationModeMember = "mockRequestValidationModeMember"; | ||
|
||
const mockConfig = { | ||
requestChecksumCalculation: () => Promise.resolve(RequestChecksumCalculation.WHEN_SUPPORTED), | ||
responseChecksumValidation: () => Promise.resolve(ResponseChecksumValidation.WHEN_SUPPORTED), | ||
} as PreviouslyResolved; | ||
|
||
afterEach(() => { | ||
expect(mockNext).toHaveBeenCalledTimes(1); | ||
vi.clearAllMocks(); | ||
}); | ||
|
||
describe("sets input.requestValidationModeMember", () => { | ||
it("when requestValidationModeMember is defined and responseChecksumValidation is supported", async () => { | ||
const mockMiddlewareConfigWithMockRequestValidationModeMember = { | ||
requestValidationModeMember: mockRequestValidationModeMember, | ||
}; | ||
const handler = flexibleChecksumsInputMiddleware( | ||
mockConfig, | ||
mockMiddlewareConfigWithMockRequestValidationModeMember | ||
)(mockNext, {}); | ||
await handler({ input: {} }); | ||
expect(mockNext).toHaveBeenCalledWith({ input: { [mockRequestValidationModeMember]: "ENABLED" } }); | ||
}); | ||
}); | ||
|
||
describe("leaves input.requestValidationModeMember", () => { | ||
const mockArgs = { input: {} }; | ||
|
||
it("when requestValidationModeMember is not defined", async () => { | ||
const handler = flexibleChecksumsInputMiddleware(mockConfig, {})(mockNext, {}); | ||
await handler(mockArgs); | ||
expect(mockNext).toHaveBeenCalledWith(mockArgs); | ||
}); | ||
|
||
it("when responseChecksumValidation is required", async () => { | ||
const mockConfigResWhenRequired = { | ||
...mockConfig, | ||
responseChecksumValidation: () => Promise.resolve(ResponseChecksumValidation.WHEN_REQUIRED), | ||
} as PreviouslyResolved; | ||
|
||
const handler = flexibleChecksumsInputMiddleware(mockConfigResWhenRequired, {})(mockNext, {}); | ||
await handler(mockArgs); | ||
|
||
expect(mockNext).toHaveBeenCalledWith(mockArgs); | ||
}); | ||
}); | ||
|
||
describe("set feature", () => { | ||
it.each([ | ||
[ | ||
"FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED", | ||
"a", | ||
"requestChecksumCalculation", | ||
RequestChecksumCalculation.WHEN_REQUIRED, | ||
], | ||
[ | ||
"FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED", | ||
"Z", | ||
"requestChecksumCalculation", | ||
RequestChecksumCalculation.WHEN_SUPPORTED, | ||
], | ||
[ | ||
"FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED", | ||
"c", | ||
"responseChecksumValidation", | ||
ResponseChecksumValidation.WHEN_REQUIRED, | ||
], | ||
[ | ||
"FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED", | ||
"b", | ||
"responseChecksumValidation", | ||
ResponseChecksumValidation.WHEN_SUPPORTED, | ||
], | ||
])("logs %s:%s when %s=%s", async (feature, value, configKey, configValue) => { | ||
const mockConfigOverride = { | ||
...mockConfig, | ||
[configKey]: () => Promise.resolve(configValue), | ||
} as PreviouslyResolved; | ||
|
||
const handler = flexibleChecksumsInputMiddleware(mockConfigOverride, {})(mockNext, {}); | ||
await handler({ input: {} }); | ||
|
||
expect(setFeature).toHaveBeenCalledTimes(2); | ||
if (configKey === "requestChecksumCalculation") { | ||
expect(setFeature).toHaveBeenNthCalledWith(1, expect.anything(), feature, value); | ||
} else { | ||
expect(setFeature).toHaveBeenNthCalledWith(2, expect.anything(), feature, value); | ||
} | ||
}); | ||
}); | ||
}); |
82 changes: 82 additions & 0 deletions
82
packages/middleware-flexible-checksums/src/flexibleChecksumsInputMiddleware.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
import { setFeature } from "@aws-sdk/core"; | ||
import { | ||
HandlerExecutionContext, | ||
MetadataBearer, | ||
RelativeMiddlewareOptions, | ||
SerializeHandler, | ||
SerializeHandlerArguments, | ||
SerializeHandlerOutput, | ||
SerializeMiddleware, | ||
} from "@smithy/types"; | ||
|
||
import { PreviouslyResolved } from "./configuration"; | ||
import { RequestChecksumCalculation, ResponseChecksumValidation } from "./constants"; | ||
|
||
export interface FlexibleChecksumsInputMiddlewareConfig { | ||
/** | ||
* Defines a top-level operation input member used to opt-in to best-effort validation | ||
* of a checksum returned in the HTTP response of the operation. | ||
*/ | ||
requestValidationModeMember?: string; | ||
} | ||
|
||
/** | ||
* @internal | ||
*/ | ||
export const flexibleChecksumsInputMiddlewareOptions: RelativeMiddlewareOptions = { | ||
name: "flexibleChecksumsInputMiddleware", | ||
toMiddleware: "serializerMiddleware", | ||
relation: "before", | ||
tags: ["BODY_CHECKSUM"], | ||
override: true, | ||
}; | ||
|
||
/** | ||
* @internal | ||
* | ||
* The input counterpart to the flexibleChecksumsMiddleware. | ||
*/ | ||
export const flexibleChecksumsInputMiddleware = | ||
( | ||
config: PreviouslyResolved, | ||
middlewareConfig: FlexibleChecksumsInputMiddlewareConfig | ||
): SerializeMiddleware<any, any> => | ||
<Output extends MetadataBearer>( | ||
next: SerializeHandler<any, Output>, | ||
context: HandlerExecutionContext | ||
): SerializeHandler<any, Output> => | ||
async (args: SerializeHandlerArguments<any>): Promise<SerializeHandlerOutput<Output>> => { | ||
const input = args.input; | ||
const { requestValidationModeMember } = middlewareConfig; | ||
|
||
const requestChecksumCalculation = await config.requestChecksumCalculation(); | ||
const responseChecksumValidation = await config.responseChecksumValidation(); | ||
|
||
switch (requestChecksumCalculation) { | ||
case RequestChecksumCalculation.WHEN_REQUIRED: | ||
setFeature(context, "FLEXIBLE_CHECKSUMS_REQ_WHEN_REQUIRED", "a"); | ||
break; | ||
case RequestChecksumCalculation.WHEN_SUPPORTED: | ||
setFeature(context, "FLEXIBLE_CHECKSUMS_REQ_WHEN_SUPPORTED", "Z"); | ||
break; | ||
} | ||
|
||
switch (responseChecksumValidation) { | ||
case ResponseChecksumValidation.WHEN_REQUIRED: | ||
setFeature(context, "FLEXIBLE_CHECKSUMS_RES_WHEN_REQUIRED", "c"); | ||
break; | ||
case ResponseChecksumValidation.WHEN_SUPPORTED: | ||
setFeature(context, "FLEXIBLE_CHECKSUMS_RES_WHEN_SUPPORTED", "b"); | ||
break; | ||
} | ||
|
||
// 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. | ||
if (responseChecksumValidation === ResponseChecksumValidation.WHEN_SUPPORTED) { | ||
input[requestValidationModeMember] = "ENABLED"; | ||
} | ||
} | ||
|
||
return next(args); | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.