UNPKG

5.9 kBJavaScriptView Raw
1// Copyright 2022 Google LLC
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
15 if (kind === "m") throw new TypeError("Private method is not writable");
16 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
17 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
18 return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
19};
20var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
21 if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
22 if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
23 return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
24};
25var _HashStreamValidator_crc32cHash, _HashStreamValidator_md5Hash, _HashStreamValidator_md5Digest;
26import { createHash } from 'crypto';
27import { Transform } from 'stream';
28import { CRC32C_DEFAULT_VALIDATOR_GENERATOR, } from './crc32c.js';
29import { FileExceptionMessages, RequestError } from './file.js';
30class HashStreamValidator extends Transform {
31 constructor(options = {}) {
32 super();
33 this.updateHashesOnly = false;
34 _HashStreamValidator_crc32cHash.set(this, undefined);
35 _HashStreamValidator_md5Hash.set(this, undefined);
36 _HashStreamValidator_md5Digest.set(this, '');
37 this.crc32cEnabled = !!options.crc32c;
38 this.md5Enabled = !!options.md5;
39 this.updateHashesOnly = !!options.updateHashesOnly;
40 this.crc32cExpected = options.crc32cExpected;
41 this.md5Expected = options.md5Expected;
42 if (this.crc32cEnabled) {
43 if (options.crc32cInstance) {
44 __classPrivateFieldSet(this, _HashStreamValidator_crc32cHash, options.crc32cInstance, "f");
45 }
46 else {
47 const crc32cGenerator = options.crc32cGenerator || CRC32C_DEFAULT_VALIDATOR_GENERATOR;
48 __classPrivateFieldSet(this, _HashStreamValidator_crc32cHash, crc32cGenerator(), "f");
49 }
50 }
51 if (this.md5Enabled) {
52 __classPrivateFieldSet(this, _HashStreamValidator_md5Hash, createHash('md5'), "f");
53 }
54 }
55 /**
56 * Return the current CRC32C value, if available.
57 */
58 get crc32c() {
59 var _a;
60 return (_a = __classPrivateFieldGet(this, _HashStreamValidator_crc32cHash, "f")) === null || _a === void 0 ? void 0 : _a.toString();
61 }
62 _flush(callback) {
63 if (__classPrivateFieldGet(this, _HashStreamValidator_md5Hash, "f")) {
64 __classPrivateFieldSet(this, _HashStreamValidator_md5Digest, __classPrivateFieldGet(this, _HashStreamValidator_md5Hash, "f").digest('base64'), "f");
65 }
66 if (this.updateHashesOnly) {
67 callback();
68 return;
69 }
70 // If we're doing validation, assume the worst-- a data integrity
71 // mismatch. If not, these tests won't be performed, and we can assume
72 // the best.
73 // We must check if the server decompressed the data on serve because hash
74 // validation is not possible in this case.
75 let failed = this.crc32cEnabled || this.md5Enabled;
76 if (this.crc32cEnabled && this.crc32cExpected) {
77 failed = !this.test('crc32c', this.crc32cExpected);
78 }
79 if (this.md5Enabled && this.md5Expected) {
80 failed = !this.test('md5', this.md5Expected);
81 }
82 if (failed) {
83 const mismatchError = new RequestError(FileExceptionMessages.DOWNLOAD_MISMATCH);
84 mismatchError.code = 'CONTENT_DOWNLOAD_MISMATCH';
85 callback(mismatchError);
86 }
87 else {
88 callback();
89 }
90 }
91 _transform(chunk, encoding, callback) {
92 this.push(chunk, encoding);
93 try {
94 if (__classPrivateFieldGet(this, _HashStreamValidator_crc32cHash, "f"))
95 __classPrivateFieldGet(this, _HashStreamValidator_crc32cHash, "f").update(chunk);
96 if (__classPrivateFieldGet(this, _HashStreamValidator_md5Hash, "f"))
97 __classPrivateFieldGet(this, _HashStreamValidator_md5Hash, "f").update(chunk);
98 callback();
99 }
100 catch (e) {
101 callback(e);
102 }
103 }
104 test(hash, sum) {
105 const check = Buffer.isBuffer(sum) ? sum.toString('base64') : sum;
106 if (hash === 'crc32c' && __classPrivateFieldGet(this, _HashStreamValidator_crc32cHash, "f")) {
107 return __classPrivateFieldGet(this, _HashStreamValidator_crc32cHash, "f").validate(check);
108 }
109 if (hash === 'md5' && __classPrivateFieldGet(this, _HashStreamValidator_md5Hash, "f")) {
110 return __classPrivateFieldGet(this, _HashStreamValidator_md5Digest, "f") === check;
111 }
112 return false;
113 }
114}
115_HashStreamValidator_crc32cHash = new WeakMap(), _HashStreamValidator_md5Hash = new WeakMap(), _HashStreamValidator_md5Digest = new WeakMap();
116export { HashStreamValidator };