Skip to content

Commit 5bc23d8

Browse files
nazar-pcbitinn
authored andcommitted
Added support for ArrayBufferView (node-fetch#457)
1 parent fa6548e commit 5bc23d8

File tree

2 files changed

+69
-11
lines changed

2 files changed

+69
-11
lines changed

src/body.js

Lines changed: 23 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,11 @@ export default function Body(body, {
3939
} else if (body instanceof Blob) {
4040
// body is blob
4141
} else if (Buffer.isBuffer(body)) {
42-
// body is buffer
43-
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
44-
// body is array buffer
42+
// body is ArrayBuffer
43+
} else if (body instanceof ArrayBuffer) {
44+
// body is ArrayBufferView
45+
} else if (ArrayBuffer.isView(body)) {
46+
// body is array buffer view
4547
} else if (body instanceof Stream) {
4648
// body is stream
4749
} else {
@@ -204,8 +206,8 @@ function consumeBody() {
204206
return Body.Promise.resolve(this.body);
205207
}
206208

207-
// body is buffer
208-
if (Object.prototype.toString.call(this.body) === '[object ArrayBuffer]') {
209+
// body is ArrayBuffer
210+
if (this.body instanceof ArrayBuffer) {
209211
return Body.Promise.resolve(Buffer.from(this.body));
210212
}
211213

@@ -416,8 +418,11 @@ export function extractContentType(instance) {
416418
} else if (Buffer.isBuffer(body)) {
417419
// body is buffer
418420
return null;
419-
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
420-
// body is array buffer
421+
} else if (body instanceof ArrayBuffer) {
422+
// body is ArrayBuffer
423+
return null;
424+
} else if (ArrayBuffer.isView(body)) {
425+
// body is ArrayBufferView
421426
return null;
422427
} else if (typeof body.getBoundary === 'function') {
423428
// detect form data input from form-data module
@@ -457,8 +462,11 @@ export function getTotalBytes(instance) {
457462
} else if (Buffer.isBuffer(body)) {
458463
// body is buffer
459464
return body.length;
460-
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
461-
// body is array buffer
465+
} else if (body instanceof ArrayBuffer) {
466+
// body is ArrayBuffer
467+
return body.byteLength;
468+
} else if (ArrayBuffer.isView(body)) {
469+
// body is ArrayBufferView
462470
return body.byteLength;
463471
} else if (body && typeof body.getLengthSync === 'function') {
464472
// detect form data input from form-data module
@@ -502,10 +510,14 @@ export function writeToStream(dest, instance) {
502510
// body is buffer
503511
dest.write(body);
504512
dest.end()
505-
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
506-
// body is array buffer
513+
} else if (body instanceof ArrayBuffer) {
514+
// body is ArrayBuffer
507515
dest.write(Buffer.from(body));
508516
dest.end()
517+
} else if (ArrayBuffer.isView(body)) {
518+
// body is ArrayBufferView
519+
dest.write(Buffer.from(body.buffer, body.byteOffset, body.byteLength));
520+
dest.end()
509521
} else {
510522
// body is stream
511523
body.pipe(dest);

test/test.js

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -875,6 +875,52 @@ describe('node-fetch', () => {
875875
});
876876
});
877877

878+
it('should allow POST request with ArrayBufferView (Uint8Array) body', function() {
879+
const url = `${base}inspect`;
880+
const opts = {
881+
method: 'POST',
882+
body: new Uint8Array(stringToArrayBuffer('Hello, world!\n'))
883+
};
884+
return fetch(url, opts).then(res => res.json()).then(res => {
885+
expect(res.method).to.equal('POST');
886+
expect(res.body).to.equal('Hello, world!\n');
887+
expect(res.headers['transfer-encoding']).to.be.undefined;
888+
expect(res.headers['content-type']).to.be.undefined;
889+
expect(res.headers['content-length']).to.equal('14');
890+
});
891+
});
892+
893+
it('should allow POST request with ArrayBufferView (DataView) body', function() {
894+
const url = `${base}inspect`;
895+
const opts = {
896+
method: 'POST',
897+
body: new DataView(stringToArrayBuffer('Hello, world!\n'))
898+
};
899+
return fetch(url, opts).then(res => res.json()).then(res => {
900+
expect(res.method).to.equal('POST');
901+
expect(res.body).to.equal('Hello, world!\n');
902+
expect(res.headers['transfer-encoding']).to.be.undefined;
903+
expect(res.headers['content-type']).to.be.undefined;
904+
expect(res.headers['content-length']).to.equal('14');
905+
});
906+
});
907+
908+
// TODO: Node.js v4 doesn't support necessary Buffer API, so we skip this test, drop this check once Node.js v4 support is not needed
909+
(Buffer.from.length === 3 ? it : it.skip)('should allow POST request with ArrayBufferView (Uint8Array, offset, length) body', function() {
910+
const url = `${base}inspect`;
911+
const opts = {
912+
method: 'POST',
913+
body: new Uint8Array(stringToArrayBuffer('Hello, world!\n'), 7, 6)
914+
};
915+
return fetch(url, opts).then(res => res.json()).then(res => {
916+
expect(res.method).to.equal('POST');
917+
expect(res.body).to.equal('world!');
918+
expect(res.headers['transfer-encoding']).to.be.undefined;
919+
expect(res.headers['content-type']).to.be.undefined;
920+
expect(res.headers['content-length']).to.equal('6');
921+
});
922+
});
923+
878924
it('should allow POST request with blob body without type', function() {
879925
const url = `${base}inspect`;
880926
const opts = {

0 commit comments

Comments
 (0)