Skip to content

Commit 6a48760

Browse files
authored
feat(middleware-flexible-checksums): use Node.js native CRC32 checksum API (#6641)
1 parent 0c558ef commit 6a48760

6 files changed

+85
-3
lines changed

packages/middleware-flexible-checksums/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,13 @@
1717
"main": "./dist-cjs/index.js",
1818
"module": "./dist-es/index.js",
1919
"browser": {
20+
"./dist-es/getCrc32ChecksumAlgorithmFunction": "./dist-es/getCrc32ChecksumAlgorithmFunction.browser",
2021
"./dist-es/streams/create-read-stream-on-buffer": "./dist-es/streams/create-read-stream-on-buffer.browser"
2122
},
2223
"react-native": {
24+
"./dist-es/getCrc32ChecksumAlgorithmFunction": "./dist-es/getCrc32ChecksumAlgorithmFunction.browser",
2325
"./dist-es/streams/create-read-stream-on-buffer": "./dist-es/streams/create-read-stream-on-buffer.browser",
26+
"./dist-cjs/getCrc32ChecksumAlgorithmFunction": "./dist-cjs/getCrc32ChecksumAlgorithmFunction.browser",
2427
"./dist-cjs/streams/create-read-stream-on-buffer": "./dist-cjs/streams/create-read-stream-on-buffer.browser"
2528
},
2629
"types": "./dist-types/index.d.ts",
@@ -32,6 +35,7 @@
3235
"dependencies": {
3336
"@aws-crypto/crc32": "5.2.0",
3437
"@aws-crypto/crc32c": "5.2.0",
38+
"@aws-crypto/util": "5.2.0",
3539
"@aws-sdk/core": "*",
3640
"@aws-sdk/types": "*",
3741
"@smithy/is-array-buffer": "^3.0.0",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import { AwsCrc32 } from "@aws-crypto/crc32";
2+
3+
export const getCrc32ChecksumAlgorithmFunction = () => AwsCrc32;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { AwsCrc32 } from "@aws-crypto/crc32";
2+
import { numToUint8 } from "@aws-crypto/util";
3+
import { describe, expect, test as it, vi } from "vitest";
4+
import * as zlib from "zlib";
5+
6+
import { getCrc32ChecksumAlgorithmFunction } from "./getCrc32ChecksumAlgorithmFunction";
7+
8+
describe(getCrc32ChecksumAlgorithmFunction.name, () => {
9+
it("returns AwsCrc32 if zlib.crc32 is undefined", () => {
10+
vi.mock("zlib", () => ({ crc32: undefined }));
11+
expect(getCrc32ChecksumAlgorithmFunction()).toBe(AwsCrc32);
12+
});
13+
14+
it("returns NodeCrc32 if zlib.crc32 is defined", async () => {
15+
const mockData = new Uint8Array([1, 2, 3]);
16+
const mockChecksum = 42;
17+
18+
// @ts-expect-error crc32 is defined only for Node.js >=v20.15.0 and >=v22.2.0.
19+
zlib.crc32 = vi
20+
.fn()
21+
.mockReturnValueOnce(mockChecksum)
22+
.mockReturnValueOnce(2 * mockChecksum);
23+
24+
const crc32Fn = getCrc32ChecksumAlgorithmFunction();
25+
expect(crc32Fn).not.toBe(AwsCrc32);
26+
27+
// @ts-expect-error crc32 is defined only for Node.js >=v20.15.0 and >=v22.2.0.
28+
expect(zlib.crc32).not.toHaveBeenCalled();
29+
const crc32 = new crc32Fn();
30+
// @ts-expect-error crc32 is defined only for Node.js >=v20.15.0 and >=v22.2.0.
31+
expect(zlib.crc32).not.toHaveBeenCalled();
32+
expect(await crc32.digest()).toEqual(numToUint8(0));
33+
34+
crc32.update(mockData);
35+
// @ts-expect-error crc32 is defined only for Node.js >=v20.15.0 and >=v22.2.0.
36+
expect(zlib.crc32).toHaveBeenCalledWith(mockData, 0);
37+
expect(await crc32.digest()).toEqual(numToUint8(mockChecksum));
38+
39+
crc32.update(mockData);
40+
// @ts-expect-error crc32 is defined only for Node.js >=v20.15.0 and >=v22.2.0.
41+
expect(zlib.crc32).toHaveBeenCalledWith(mockData, mockChecksum);
42+
expect(await crc32.digest()).toEqual(numToUint8(2 * mockChecksum));
43+
44+
crc32.reset();
45+
expect(await crc32.digest()).toEqual(numToUint8(0));
46+
});
47+
});
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { AwsCrc32 } from "@aws-crypto/crc32";
2+
import { numToUint8 } from "@aws-crypto/util";
3+
import { Checksum } from "@smithy/types";
4+
import * as zlib from "zlib";
5+
6+
export const getCrc32ChecksumAlgorithmFunction = () => {
7+
// @ts-expect-error crc32 is defined only for Node.js >=v20.15.0 and >=v22.2.0.
8+
if (typeof zlib.crc32 === "undefined") {
9+
return AwsCrc32;
10+
}
11+
12+
return class NodeCrc32 implements Checksum {
13+
checksum = 0;
14+
15+
update(data: Uint8Array) {
16+
// @ts-expect-error crc32 is defined only for Node.js >=v20.15.0 and >=v22.2.0.
17+
this.checksum = zlib.crc32(data, this.checksum);
18+
}
19+
20+
async digest() {
21+
return numToUint8(this.checksum);
22+
}
23+
24+
reset() {
25+
this.checksum = 0;
26+
}
27+
};
28+
};

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import { AwsCrc32 } from "@aws-crypto/crc32";
21
import { AwsCrc32c } from "@aws-crypto/crc32c";
32
import { ChecksumConstructor, HashConstructor } from "@smithy/types";
43

54
import { PreviouslyResolved } from "./configuration";
65
import { ChecksumAlgorithm } from "./constants";
6+
import { getCrc32ChecksumAlgorithmFunction } from "./getCrc32ChecksumAlgorithmFunction";
77

88
/**
99
* Returns the function that will compute the checksum for the given {@link ChecksumAlgorithm}.
@@ -14,7 +14,7 @@ export const selectChecksumAlgorithmFunction = (
1414
): ChecksumConstructor | HashConstructor =>
1515
({
1616
[ChecksumAlgorithm.MD5]: config.md5,
17-
[ChecksumAlgorithm.CRC32]: AwsCrc32,
17+
[ChecksumAlgorithm.CRC32]: getCrc32ChecksumAlgorithmFunction(),
1818
[ChecksumAlgorithm.CRC32C]: AwsCrc32c,
1919
[ChecksumAlgorithm.SHA1]: config.sha1,
2020
[ChecksumAlgorithm.SHA256]: config.sha256,

yarn.lock

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@
7474
dependencies:
7575
tslib "^2.6.2"
7676

77-
"@aws-crypto/util@^5.2.0":
77+
"@aws-crypto/util@5.2.0", "@aws-crypto/util@^5.2.0":
7878
version "5.2.0"
7979
resolved "https://registry.npmjs.org/@aws-crypto/util/-/util-5.2.0.tgz"
8080
integrity sha512-4RkU9EsI6ZpBve5fseQlGNUWKMa1RLPQ1dnjnQoe07ldfIzcsGb5hC5W0Dm7u423KWzawlrpbjXBrXCEv9zazQ==

0 commit comments

Comments
 (0)