Skip to content

Commit

Permalink
Fixing default transformRequest with buffer pools (#1511)
Browse files Browse the repository at this point in the history
* 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 <delventhalz@gmail.com>

* 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 <delventhalz@gmail.com>

Co-authored-by: Zac Delventhal <zac@bitwise.io>
Co-authored-by: Jay <jasonsaayman@gmail.com>
  • Loading branch information
3 people committed May 27, 2020
1 parent 8a8c534 commit a9a3b5e
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/defaults.js
Expand Up @@ -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');
Expand Down
6 changes: 6 additions & 0 deletions test/specs/defaults.spec.js
Expand Up @@ -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"}');

Expand Down

0 comments on commit a9a3b5e

Please sign in to comment.