Fix up ArrayBufferView support (#464)
Also add more test coverage. Fixes: #482 Closes: #484
This commit is contained in:
parent
287bc3bdcf
commit
b091ab5917
19
src/body.js
19
src/body.js
|
@ -39,11 +39,11 @@ export default function Body(body, {
|
|||
} else if (body instanceof Blob) {
|
||||
// body is blob
|
||||
} else if (Buffer.isBuffer(body)) {
|
||||
// body is Buffer
|
||||
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
|
||||
// body is ArrayBuffer
|
||||
} else if (body instanceof ArrayBuffer) {
|
||||
// body is ArrayBufferView
|
||||
} else if (ArrayBuffer.isView(body)) {
|
||||
// body is array buffer view
|
||||
// body is ArrayBufferView
|
||||
} else if (body instanceof Stream) {
|
||||
// body is stream
|
||||
} else {
|
||||
|
@ -207,10 +207,15 @@ function consumeBody() {
|
|||
}
|
||||
|
||||
// body is ArrayBuffer
|
||||
if (this.body instanceof ArrayBuffer) {
|
||||
if (Object.prototype.toString.call(this.body) === '[object ArrayBuffer]') {
|
||||
return Body.Promise.resolve(Buffer.from(this.body));
|
||||
}
|
||||
|
||||
// body is ArrayBufferView
|
||||
if (ArrayBuffer.isView(this.body)) {
|
||||
return Body.Promise.resolve(Buffer.from(this.body.buffer, this.body.byteOffset, this.body.byteLength));
|
||||
}
|
||||
|
||||
// istanbul ignore if: should never happen
|
||||
if (!(this.body instanceof Stream)) {
|
||||
return Body.Promise.resolve(Buffer.alloc(0));
|
||||
|
@ -418,7 +423,7 @@ export function extractContentType(instance) {
|
|||
} else if (Buffer.isBuffer(body)) {
|
||||
// body is buffer
|
||||
return null;
|
||||
} else if (body instanceof ArrayBuffer) {
|
||||
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
|
||||
// body is ArrayBuffer
|
||||
return null;
|
||||
} else if (ArrayBuffer.isView(body)) {
|
||||
|
@ -462,7 +467,7 @@ export function getTotalBytes(instance) {
|
|||
} else if (Buffer.isBuffer(body)) {
|
||||
// body is buffer
|
||||
return body.length;
|
||||
} else if (body instanceof ArrayBuffer) {
|
||||
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
|
||||
// body is ArrayBuffer
|
||||
return body.byteLength;
|
||||
} else if (ArrayBuffer.isView(body)) {
|
||||
|
@ -510,7 +515,7 @@ export function writeToStream(dest, instance) {
|
|||
// body is buffer
|
||||
dest.write(body);
|
||||
dest.end()
|
||||
} else if (body instanceof ArrayBuffer) {
|
||||
} else if (Object.prototype.toString.call(body) === '[object ArrayBuffer]') {
|
||||
// body is ArrayBuffer
|
||||
dest.write(Buffer.from(body));
|
||||
dest.end()
|
||||
|
|
82
test/test.js
82
test/test.js
|
@ -18,6 +18,12 @@ const path = require('path');
|
|||
const stream = require('stream');
|
||||
const { parse: parseURL, URLSearchParams } = require('url');
|
||||
const { lookup } = require('dns');
|
||||
const vm = require('vm');
|
||||
|
||||
const {
|
||||
ArrayBuffer: VMArrayBuffer,
|
||||
Uint8Array: VMUint8Array
|
||||
} = vm.runInNewContext('this');
|
||||
|
||||
let convert;
|
||||
try { convert = require('encoding').convert; } catch(e) { }
|
||||
|
@ -876,6 +882,27 @@ describe('node-fetch', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should allow POST request with ArrayBuffer body from a VM context', function() {
|
||||
// TODO: Node.js v4 doesn't support ArrayBuffer from other contexts, so we skip this test, drop this check once Node.js v4 support is not needed
|
||||
try {
|
||||
Buffer.from(new VMArrayBuffer());
|
||||
} catch (err) {
|
||||
this.skip();
|
||||
}
|
||||
const url = `${base}inspect`;
|
||||
const opts = {
|
||||
method: 'POST',
|
||||
body: new VMUint8Array(Buffer.from('Hello, world!\n')).buffer
|
||||
};
|
||||
return fetch(url, opts).then(res => res.json()).then(res => {
|
||||
expect(res.method).to.equal('POST');
|
||||
expect(res.body).to.equal('Hello, world!\n');
|
||||
expect(res.headers['transfer-encoding']).to.be.undefined;
|
||||
expect(res.headers['content-type']).to.be.undefined;
|
||||
expect(res.headers['content-length']).to.equal('14');
|
||||
});
|
||||
});
|
||||
|
||||
it('should allow POST request with ArrayBufferView (Uint8Array) body', function() {
|
||||
const url = `${base}inspect`;
|
||||
const opts = {
|
||||
|
@ -906,6 +933,27 @@ describe('node-fetch', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should allow POST request with ArrayBufferView (Uint8Array) body from a VM context', function() {
|
||||
// TODO: Node.js v4 doesn't support ArrayBufferView from other contexts, so we skip this test, drop this check once Node.js v4 support is not needed
|
||||
try {
|
||||
Buffer.from(new VMArrayBuffer());
|
||||
} catch (err) {
|
||||
this.skip();
|
||||
}
|
||||
const url = `${base}inspect`;
|
||||
const opts = {
|
||||
method: 'POST',
|
||||
body: new VMUint8Array(Buffer.from('Hello, world!\n'))
|
||||
};
|
||||
return fetch(url, opts).then(res => res.json()).then(res => {
|
||||
expect(res.method).to.equal('POST');
|
||||
expect(res.body).to.equal('Hello, world!\n');
|
||||
expect(res.headers['transfer-encoding']).to.be.undefined;
|
||||
expect(res.headers['content-type']).to.be.undefined;
|
||||
expect(res.headers['content-length']).to.equal('14');
|
||||
});
|
||||
});
|
||||
|
||||
// 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
|
||||
(Buffer.from.length === 3 ? it : it.skip)('should allow POST request with ArrayBufferView (Uint8Array, offset, length) body', function() {
|
||||
const url = `${base}inspect`;
|
||||
|
@ -1919,6 +1967,20 @@ describe('Response', function () {
|
|||
});
|
||||
});
|
||||
|
||||
it('should support Uint8Array as body', function() {
|
||||
const res = new Response(new Uint8Array(stringToArrayBuffer('a=1')));
|
||||
return res.text().then(result => {
|
||||
expect(result).to.equal('a=1');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support DataView as body', function() {
|
||||
const res = new Response(new DataView(stringToArrayBuffer('a=1')));
|
||||
return res.text().then(result => {
|
||||
expect(result).to.equal('a=1');
|
||||
});
|
||||
});
|
||||
|
||||
it('should default to null as body', function() {
|
||||
const res = new Response();
|
||||
expect(res.body).to.equal(null);
|
||||
|
@ -2124,6 +2186,26 @@ describe('Request', function () {
|
|||
expect(result).to.equal('a=1');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support Uint8Array as body', function() {
|
||||
const req = new Request('', {
|
||||
method: 'POST',
|
||||
body: new Uint8Array(stringToArrayBuffer('a=1'))
|
||||
});
|
||||
return req.text().then(result => {
|
||||
expect(result).to.equal('a=1');
|
||||
});
|
||||
});
|
||||
|
||||
it('should support DataView as body', function() {
|
||||
const req = new Request('', {
|
||||
method: 'POST',
|
||||
body: new DataView(stringToArrayBuffer('a=1'))
|
||||
});
|
||||
return req.text().then(result => {
|
||||
expect(result).to.equal('a=1');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
function streamToPromise(stream, dataHandler) {
|
||||
|
|
Loading…
Reference in New Issue