Skip to content

Commit

Permalink
chore(middleware-flexible-checksums): use RequestChecksumCalculation
Browse files Browse the repository at this point in the history
  • Loading branch information
trivikr committed Sep 17, 2024
1 parent 9b2dac1 commit 85082a3
Show file tree
Hide file tree
Showing 5 changed files with 104 additions and 21 deletions.
6 changes: 6 additions & 0 deletions packages/middleware-flexible-checksums/src/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import {
Encoder,
GetAwsChunkedEncodingStream,
HashConstructor,
Provider,
StreamCollector,
StreamHasher,
} from "@smithy/types";
Expand Down Expand Up @@ -31,6 +32,11 @@ export interface PreviouslyResolved {
*/
md5: ChecksumConstructor | HashConstructor;

/**
* Determines when a checksum will be calculated for request payloads
*/
requestChecksumCalculation: Provider<string>;

/**
* A constructor for a class implementing the {@link Hash} interface that computes SHA1 hashes.
* @internal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { HttpRequest } from "@smithy/protocol-http";
import { BuildHandlerArguments } from "@smithy/types";

import { PreviouslyResolved } from "./configuration";
import { ChecksumAlgorithm } from "./constants";
import { ChecksumAlgorithm, RequestChecksumCalculation } from "./constants";
import { flexibleChecksumsMiddleware } from "./flexibleChecksumsMiddleware";
import { getChecksumAlgorithmForRequest } from "./getChecksumAlgorithmForRequest";
import { getChecksumLocationName } from "./getChecksumLocationName";
Expand All @@ -27,7 +27,9 @@ describe(flexibleChecksumsMiddleware.name, () => {
const mockChecksumLocationName = "mock-checksum-location-name";

const mockInput = {};
const mockConfig = {} as PreviouslyResolved;
const mockConfig = {
requestChecksumCalculation: () => Promise.resolve(RequestChecksumCalculation.WHEN_REQUIRED),
} as PreviouslyResolved;
const mockMiddlewareConfig = { input: mockInput, requestChecksumRequired: false };

const mockBody = { body: "mockRequestBody" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,15 @@ export const flexibleChecksumsMiddleware =
const { request } = args;
const { body: requestBody, headers } = request;
const { base64Encoder, streamHasher } = config;
const requestChecksumCalculation = await config.requestChecksumCalculation();
const { input, requestChecksumRequired, requestAlgorithmMember } = middlewareConfig;

const checksumAlgorithm = getChecksumAlgorithmForRequest(
input,
{
requestChecksumRequired,
requestAlgorithmMember,
requestChecksumCalculation,
},
!!context.isS3ExpressBucket
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,41 +1,93 @@
import { ChecksumAlgorithm } from "./constants";
import { DEFAULT_CHECKSUM_ALGORITHM, RequestChecksumCalculation } from "./constants";
import { getChecksumAlgorithmForRequest } from "./getChecksumAlgorithmForRequest";
import { CLIENT_SUPPORTED_ALGORITHMS } from "./types";

describe(getChecksumAlgorithmForRequest.name, () => {
const mockRequestAlgorithmMember = "mockRequestAlgorithmMember";

describe("when requestAlgorithmMember is not provided", () => {
it("returns MD5 if requestChecksumRequired is set", () => {
expect(getChecksumAlgorithmForRequest({}, { requestChecksumRequired: true })).toEqual(ChecksumAlgorithm.MD5);
describe(`when requestChecksumCalculation is '${RequestChecksumCalculation.WHEN_REQUIRED}'`, () => {
const mockOptions = { requestChecksumCalculation: RequestChecksumCalculation.WHEN_REQUIRED };

it(`returns ${DEFAULT_CHECKSUM_ALGORITHM} if requestChecksumRequired is set`, () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: true })).toEqual(
DEFAULT_CHECKSUM_ALGORITHM
);
});

it("returns undefined if requestChecksumRequired is false", () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: false })).toBeUndefined();
});
});

it("returns undefined if requestChecksumRequired is false", () => {
expect(getChecksumAlgorithmForRequest({}, { requestChecksumRequired: false })).toBeUndefined();
describe(`when requestChecksumCalculation is '${RequestChecksumCalculation.WHEN_SUPPORTED}'`, () => {
const mockOptions = { requestChecksumCalculation: RequestChecksumCalculation.WHEN_SUPPORTED };

it(`returns ${DEFAULT_CHECKSUM_ALGORITHM} if requestChecksumRequired is set`, () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: true })).toEqual(
DEFAULT_CHECKSUM_ALGORITHM
);
});

it(`returns ${DEFAULT_CHECKSUM_ALGORITHM} if requestChecksumRequired is false`, () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: false })).toEqual(
DEFAULT_CHECKSUM_ALGORITHM
);
});
});
});

describe("when requestAlgorithmMember is not set in input", () => {
const mockOptions = { requestAlgorithmMember: mockRequestAlgorithmMember };
const mockOptionsWithAlgoMember = { requestAlgorithmMember: mockRequestAlgorithmMember };

it("returns MD5 if requestChecksumRequired is set", () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: true })).toEqual(
ChecksumAlgorithm.MD5
);
describe(`when requestChecksumCalculation is '${RequestChecksumCalculation.WHEN_REQUIRED}'`, () => {
const mockOptions = {
...mockOptionsWithAlgoMember,
requestChecksumCalculation: RequestChecksumCalculation.WHEN_REQUIRED,
};

it(`returns ${DEFAULT_CHECKSUM_ALGORITHM} if requestChecksumRequired is set`, () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: true })).toEqual(
DEFAULT_CHECKSUM_ALGORITHM
);
});

it("returns undefined if requestChecksumRequired is false", () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: false })).toBeUndefined();
});
});

it("returns undefined if requestChecksumRequired is false", () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: false })).toBeUndefined();
describe(`when requestChecksumCalculation is '${RequestChecksumCalculation.WHEN_SUPPORTED}'`, () => {
const mockOptions = {
...mockOptionsWithAlgoMember,
requestChecksumCalculation: RequestChecksumCalculation.WHEN_SUPPORTED,
};

it(`returns ${DEFAULT_CHECKSUM_ALGORITHM} if requestChecksumRequired is set`, () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: true })).toEqual(
DEFAULT_CHECKSUM_ALGORITHM
);
});

it(`returns ${DEFAULT_CHECKSUM_ALGORITHM} if requestChecksumRequired is false`, () => {
expect(getChecksumAlgorithmForRequest({}, { ...mockOptions, requestChecksumRequired: false })).toEqual(
DEFAULT_CHECKSUM_ALGORITHM
);
});
});
});

it("throws error if input[requestAlgorithmMember] if not supported by client", () => {
const unsupportedAlgo = "unsupportedAlgo";
const mockInput = { [mockRequestAlgorithmMember]: unsupportedAlgo };
const mockOptions = { requestChecksumRequired: true, requestAlgorithmMember: mockRequestAlgorithmMember };
const mockOptions = {
requestChecksumRequired: true,
requestAlgorithmMember: mockRequestAlgorithmMember,
requestChecksumCalculation: RequestChecksumCalculation.WHEN_REQUIRED,
};
expect(() => {
getChecksumAlgorithmForRequest(mockInput, mockOptions);
}).toThrowError(
}).toThrow(
`The checksum algorithm "${unsupportedAlgo}" is not supported by the client.` +
` Select one of ${CLIENT_SUPPORTED_ALGORITHMS}.`
);
Expand All @@ -44,7 +96,11 @@ describe(getChecksumAlgorithmForRequest.name, () => {
describe("returns input[requestAlgorithmMember] if supported by client", () => {
it.each(CLIENT_SUPPORTED_ALGORITHMS)("Supported algorithm: %s", (supportedAlgorithm) => {
const mockInput = { [mockRequestAlgorithmMember]: supportedAlgorithm };
const mockOptions = { requestChecksumRequired: true, requestAlgorithmMember: mockRequestAlgorithmMember };
const mockOptions = {
requestChecksumRequired: true,
requestAlgorithmMember: mockRequestAlgorithmMember,
requestChecksumCalculation: RequestChecksumCalculation.WHEN_REQUIRED,
};
expect(getChecksumAlgorithmForRequest(mockInput, mockOptions)).toEqual(supportedAlgorithm);
});
});
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
import { ChecksumAlgorithm, DEFAULT_CHECKSUM_ALGORITHM, S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM } from "./constants";
import {
ChecksumAlgorithm,
DEFAULT_CHECKSUM_ALGORITHM,
RequestChecksumCalculation,
S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM,
} from "./constants";
import { CLIENT_SUPPORTED_ALGORITHMS } from "./types";

export interface GetChecksumAlgorithmForRequestOptions {
Expand All @@ -11,6 +16,11 @@ export interface GetChecksumAlgorithmForRequestOptions {
* Defines a top-level operation input member that is used to configure request checksum behavior.
*/
requestAlgorithmMember?: string;

/**
* Determines when a checksum will be calculated for request payloads
*/
requestChecksumCalculation: string;
}

/**
Expand All @@ -20,16 +30,23 @@ export interface GetChecksumAlgorithmForRequestOptions {
*/
export const getChecksumAlgorithmForRequest = (
input: any,
{ requestChecksumRequired, requestAlgorithmMember }: GetChecksumAlgorithmForRequestOptions,
{
requestChecksumRequired,
requestAlgorithmMember,
requestChecksumCalculation,
}: GetChecksumAlgorithmForRequestOptions,
isS3Express?: boolean
): ChecksumAlgorithm | undefined => {
const defaultAlgorithm = isS3Express ? S3_EXPRESS_DEFAULT_CHECKSUM_ALGORITHM : DEFAULT_CHECKSUM_ALGORITHM;

// Either the Operation input member that is used to configure request checksum behavior is not set, or
// the value for input member to configure flexible checksum is not set.
if (!requestAlgorithmMember || !input[requestAlgorithmMember]) {
// Select an algorithm only if request checksum is required.
return requestChecksumRequired ? defaultAlgorithm : undefined;
// Select an algorithm only if request checksum calculation is supported
// or request checksum is required.
return requestChecksumCalculation === RequestChecksumCalculation.WHEN_SUPPORTED || requestChecksumRequired
? defaultAlgorithm
: undefined;
}

const checksumAlgorithm = input[requestAlgorithmMember];
Expand Down

0 comments on commit 85082a3

Please sign in to comment.