Skip to content

Commit

Permalink
chore: use requestAlgorithmMemberHttpHeader to populate header
Browse files Browse the repository at this point in the history
  • Loading branch information
trivikr committed Dec 3, 2024
1 parent 7c00c7e commit 04a0a9e
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 146 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -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 = {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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" };
Expand Down Expand Up @@ -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);
});
});
});
Expand All @@ -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" };
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -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,
Expand Down

0 comments on commit 04a0a9e

Please sign in to comment.