Skip to content

Commit

Permalink
fix(middleware-flexible-checksums): skip checksum computation if prov…
Browse files Browse the repository at this point in the history
…ided (#6745)
  • Loading branch information
trivikr authored Dec 17, 2024
1 parent a116e07 commit e1678f8
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { flexibleChecksumsMiddleware } from "./flexibleChecksumsMiddleware";
import { getChecksumAlgorithmForRequest } from "./getChecksumAlgorithmForRequest";
import { getChecksumLocationName } from "./getChecksumLocationName";
import { hasHeader } from "./hasHeader";
import { hasHeaderWithPrefix } from "./hasHeaderWithPrefix";
import { isStreaming } from "./isStreaming";
import { selectChecksumAlgorithmFunction } from "./selectChecksumAlgorithmFunction";
import { stringHasher } from "./stringHasher";
Expand All @@ -16,6 +17,7 @@ vi.mock("@smithy/protocol-http");
vi.mock("./getChecksumAlgorithmForRequest");
vi.mock("./getChecksumLocationName");
vi.mock("./hasHeader");
vi.mock("./hasHeaderWithPrefix");
vi.mock("./isStreaming");
vi.mock("./selectChecksumAlgorithmFunction");
vi.mock("./stringHasher");
Expand Down Expand Up @@ -44,6 +46,7 @@ describe(flexibleChecksumsMiddleware.name, () => {
vi.mocked(getChecksumAlgorithmForRequest).mockReturnValue(ChecksumAlgorithm.MD5);
vi.mocked(getChecksumLocationName).mockReturnValue(mockChecksumLocationName);
vi.mocked(hasHeader).mockReturnValue(true);
vi.mocked(hasHeaderWithPrefix).mockReturnValue(false);
vi.mocked(isStreaming).mockReturnValue(false);
vi.mocked(selectChecksumAlgorithmFunction).mockReturnValue(mockChecksumAlgorithmFunction);
});
Expand All @@ -63,31 +66,28 @@ describe(flexibleChecksumsMiddleware.name, () => {
});

describe("request checksum", () => {
afterEach(() => {
expect(getChecksumAlgorithmForRequest).toHaveBeenCalledTimes(1);
});

it("if checksumAlgorithm is not defined", async () => {
vi.mocked(getChecksumAlgorithmForRequest).mockReturnValue(undefined);
const handler = flexibleChecksumsMiddleware(mockConfig, mockMiddlewareConfig)(mockNext, {});
await handler(mockArgs);
expect(hasHeaderWithPrefix).toHaveBeenCalledTimes(1);
expect(getChecksumLocationName).not.toHaveBeenCalled();
expect(mockNext).toHaveBeenCalledWith(mockArgs);
expect(selectChecksumAlgorithmFunction).not.toHaveBeenCalled();
expect(getChecksumAlgorithmForRequest).toHaveBeenCalledTimes(1);
});

it("if header is already present", async () => {
const handler = flexibleChecksumsMiddleware(mockConfig, mockMiddlewareConfig)(mockNext, {});
const mockHeadersWithChecksumHeader = { ...mockHeaders, [mockChecksumLocationName]: "mockHeaderValue" };
const mockArgsWithChecksumHeader = {
...mockArgs,
request: { ...mockRequest, headers: mockHeadersWithChecksumHeader },
};
await handler(mockArgsWithChecksumHeader);
expect(getChecksumLocationName).toHaveBeenCalledWith(ChecksumAlgorithm.MD5);
expect(selectChecksumAlgorithmFunction).toHaveBeenCalledWith(ChecksumAlgorithm.MD5, mockConfig);
expect(mockNext).toHaveBeenCalledWith(mockArgsWithChecksumHeader);
expect(hasHeader).toHaveBeenCalledWith(mockChecksumLocationName, mockHeadersWithChecksumHeader);
vi.mocked(hasHeaderWithPrefix).mockReturnValue(true);

await handler(mockArgs);

expect(hasHeaderWithPrefix).toHaveBeenCalledTimes(1);
expect(getChecksumLocationName).not.toHaveBeenCalled();
expect(selectChecksumAlgorithmFunction).not.toHaveBeenCalled();
expect(hasHeader).not.toHaveBeenCalled();
expect(mockNext).toHaveBeenCalledWith(mockArgs);
});
});
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { ChecksumAlgorithm } from "./constants";
import { getChecksumAlgorithmForRequest } from "./getChecksumAlgorithmForRequest";
import { getChecksumLocationName } from "./getChecksumLocationName";
import { hasHeader } from "./hasHeader";
import { hasHeaderWithPrefix } from "./hasHeaderWithPrefix";
import { isStreaming } from "./isStreaming";
import { selectChecksumAlgorithmFunction } from "./selectChecksumAlgorithmFunction";
import { stringHasher } from "./stringHasher";
Expand Down Expand Up @@ -64,6 +65,10 @@ export const flexibleChecksumsMiddleware =
return next(args);
}

if (hasHeaderWithPrefix("x-amz-checksum-", args.request.headers)) {
return next(args);
}

const { request, input } = args;
const { body: requestBody, headers } = request;
const { base64Encoder, streamHasher } = config;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { HeaderBag } from "@smithy/types";
import { describe, expect, test as it } from "vitest";

import { hasHeaderWithPrefix } from "./hasHeaderWithPrefix";

describe(hasHeaderWithPrefix.name, () => {
const mockHeaders: HeaderBag = {
"header-prefix-lowercase-1": "header-value-1",
"HEADER-PREFIX-UPPERCASE-2": "header-value-2",
};

describe("contains header prefix", () => {
it("when headerPrefix is exact", () => {
expect(hasHeaderWithPrefix("header-prefix-lowercase-", mockHeaders)).toBe(true);
});

it("when headerPrefix is in different case", () => {
expect(hasHeaderWithPrefix("HEADER-PREFIX-LOWERCASE-", mockHeaders)).toBe(true);
});

it("when headerPrefix in headers is in different case", () => {
expect(hasHeaderWithPrefix("header-prefix-uppercase-", mockHeaders)).toBe(true);
});
});

it("doesn't contain header with headerPrefix", () => {
expect(hasHeaderWithPrefix("header-prefix-3", mockHeaders)).toBe(false);
});
});
15 changes: 15 additions & 0 deletions packages/middleware-flexible-checksums/src/hasHeaderWithPrefix.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { HeaderBag } from "@smithy/types";

/**
* Returns true if header with headerPrefix is present in headers.
* Comparisons are case-insensitive.
*/
export const hasHeaderWithPrefix = (headerPrefix: string, headers: HeaderBag): boolean => {
const soughtHeaderPrefix = headerPrefix.toLowerCase();
for (const headerName of Object.keys(headers)) {
if (headerName.toLowerCase().startsWith(soughtHeaderPrefix)) {
return true;
}
}
return false;
};

0 comments on commit e1678f8

Please sign in to comment.