From a9a3b5e22b1e1d577d52ec636be6f690ebd2d655 Mon Sep 17 00:00:00 2001 From: Zac Delventhal Date: Wed, 27 May 2020 07:42:41 -0500 Subject: [PATCH] Fixing default transformRequest with buffer pools (#1511) * Fixing default transformRequest of TypedArrays with buffer pools A buffer pool is a large ArrayBuffer of a preset size used with a TypedArray such as Uint8Array. This can speed up performance when constructing TypedArrays of unknown sizes, and is a technique used by Node with their Buffers, and by libraries like dcodeIO/protobuf.js. Because the ArrayBuffer of such a TypedArray is much longer than the array itself, using `.buffer` to transform the array before POSTing results in sending a request with many extraneous empty bytes, which is wastefule and may result in unexpected behavior. Using `.slice()` before grabbing the ArrayBuffer fixes the problem by creating a new TypedArray with a buffer of the expected length. Signed-off-by: Zac Delventhal * Adding test for using default transformRequest with buffer pools Adds a new test to the default transformRequest, running it on a Uint8Array with a byte length of 16, but a much larger ArrayBuffer with a byte length of 256. The transformed array should not include any extra bytes, and so must have a byte length of just 16. Signed-off-by: Zac Delventhal Co-authored-by: Zac Delventhal Co-authored-by: Jay --- lib/defaults.js | 2 +- test/specs/defaults.spec.js | 6 ++++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/defaults.js b/lib/defaults.js index 2b2a1a7d55..2a9d56378f 100644 --- a/lib/defaults.js +++ b/lib/defaults.js @@ -41,7 +41,7 @@ var defaults = { return data; } if (utils.isArrayBufferView(data)) { - return data.buffer; + return data.slice().buffer; } if (utils.isURLSearchParams(data)) { setContentTypeIfUnset(headers, 'application/x-www-form-urlencoded;charset=utf-8'); diff --git a/test/specs/defaults.spec.js b/test/specs/defaults.spec.js index c8ee72eab2..92fb6d8c29 100644 --- a/test/specs/defaults.spec.js +++ b/test/specs/defaults.spec.js @@ -24,6 +24,12 @@ describe('defaults', function () { expect(defaults.transformRequest[0]('foo=bar')).toEqual('foo=bar'); }); + it('should transform TypedArrays without including buffer pool', function () { + if (typeof Uint8Array === 'undefined') return this.skip(); + const buffered = new Uint8Array(256).subarray(10, 26); + expect(defaults.transformRequest[0](buffered).byteLength).toEqual(16); + }); + it('should transform response json', function () { var data = defaults.transformResponse[0]('{"foo":"bar"}');