From 1f221c72663a52d19c06ff6ff63debefb863cc9a Mon Sep 17 00:00:00 2001 From: Sameena Shaffeeullah Date: Fri, 19 Nov 2021 13:56:53 -0800 Subject: [PATCH] Revert "fix: revert skip validation (#1718)" This reverts commit 0c75e33eb0291aa7dfc704c86733f4c0dc78d322. --- src/file.ts | 18 ++++++++++++++---- system-test/storage.ts | 27 +++++++++++++++++++++++++++ test/file.ts | 18 ++++++++++++++++++ 3 files changed, 59 insertions(+), 4 deletions(-) diff --git a/src/file.ts b/src/file.ts index 4d169b4fe..727408926 100644 --- a/src/file.ts +++ b/src/file.ts @@ -1272,7 +1272,7 @@ class File extends ServiceObject { const throughStream = streamEvents(new PassThrough()); - let isCompressed = true; + let isServedCompressed = true; let crc32c = true; let md5 = false; @@ -1379,7 +1379,7 @@ class File extends ServiceObject { rawResponseStream.on('error', onComplete); const headers = rawResponseStream.toJSON().headers; - isCompressed = headers['content-encoding'] === 'gzip'; + isServedCompressed = headers['content-encoding'] === 'gzip'; const throughStreams: Writable[] = []; if (shouldRunValidation) { @@ -1400,7 +1400,7 @@ class File extends ServiceObject { throughStreams.push(validateStream); } - if (isCompressed && options.decompress) { + if (isServedCompressed && options.decompress) { throughStreams.push(zlib.createGunzip()); } @@ -1440,13 +1440,23 @@ class File extends ServiceObject { return; } - if (!isCompressed) { + // TODO(https://github.com/googleapis/nodejs-storage/issues/709): + // Remove once the backend issue is fixed. + // If object is stored compressed (having + // metadata.contentEncoding === 'gzip') and was served decompressed, + // then skip checksum validation because the remote checksum is computed + // against the compressed version of the object. + if (!isServedCompressed) { try { await this.getMetadata({userProject: options.userProject}); } catch (e) { throughStream.destroy(e); return; } + if (this.metadata.contentEncoding === 'gzip') { + throughStream.end(); + return; + } } // If we're doing validation, assume the worst-- a data integrity diff --git a/system-test/storage.ts b/system-test/storage.ts index 9b7137dcd..5083d700c 100644 --- a/system-test/storage.ts +++ b/system-test/storage.ts @@ -2502,6 +2502,33 @@ describe('storage', () => { }); }); + it('should skip validation if file is served decompressed', async () => { + const filename = 'logo-gzipped.png'; + await bucket.upload(FILES.logo.path, {destination: filename, gzip: true}); + + tmp.setGracefulCleanup(); + const {name: tmpFilePath} = tmp.fileSync(); + + const file = bucket.file(filename); + + await new Promise((resolve, reject) => { + file + .createReadStream() + .on('error', reject) + .on('response', raw => { + assert.strictEqual( + raw.toJSON().headers['content-encoding'], + undefined + ); + }) + .pipe(fs.createWriteStream(tmpFilePath)) + .on('error', reject) + .on('finish', resolve); + }); + + await file.delete(); + }); + describe('simple write', () => { it('should save arbitrary data', done => { const file = bucket.file('TestFile'); diff --git a/test/file.ts b/test/file.ts index b02da5da7..445f0bde8 100644 --- a/test/file.ts +++ b/test/file.ts @@ -1387,6 +1387,24 @@ describe('File', () => { file.requestStream = getFakeSuccessfulRequest(data); }); + describe('server decompression', () => { + it('should skip validation if file was stored compressed', done => { + file.metadata.contentEncoding = 'gzip'; + + const validateStub = sinon.stub().returns(true); + fakeValidationStream.test = validateStub; + + file + .createReadStream({validation: 'crc32c'}) + .on('error', done) + .on('end', () => { + assert(validateStub.notCalled); + done(); + }) + .resume(); + }); + }); + it('should emit errors from the validation stream', done => { const error = new Error('Error.');