diff --git a/lib/fetch/body.js b/lib/fetch/body.js index 08d22310a38..f70fbb7d27d 100644 --- a/lib/fetch/body.js +++ b/lib/fetch/body.js @@ -57,16 +57,16 @@ function extractBody (object, keepalive = false) { // Set Content-Type to `application/x-www-form-urlencoded;charset=UTF-8`. contentType = 'application/x-www-form-urlencoded;charset=UTF-8' - } else if (isArrayBuffer(object) || ArrayBuffer.isView(object)) { - // BufferSource + } else if (isArrayBuffer(object)) { + // BufferSource/ArrayBuffer - if (object instanceof DataView) { - // TODO: Blob doesn't seem to work with DataView? - object = object.buffer - } + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.slice()) + } else if (ArrayBuffer.isView(object)) { + // BufferSource/ArrayBufferView // Set source to a copy of the bytes held by object. - source = new Uint8Array(object) + source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) } else if (util.isFormDataLike(object)) { const boundary = '----formdata-undici-' + Math.random() const prefix = `--${boundary}\r\nContent-Disposition: form-data` diff --git a/test/node-fetch/main.js b/test/node-fetch/main.js index a6d1501f40d..7066aeb825f 100644 --- a/test/node-fetch/main.js +++ b/test/node-fetch/main.js @@ -1032,6 +1032,22 @@ describe('node-fetch', () => { }) }) + it('should allow POST request with ArrayBufferView (BigUint64Array) body', () => { + const encoder = new TextEncoder() + const url = `${base}inspect` + const options = { + method: 'POST', + body: new BigUint64Array(encoder.encode('0123456789abcdef').buffer) + } + return fetch(url, options).then(res => res.json()).then(res => { + expect(res.method).to.equal('POST') + expect(res.body).to.equal('0123456789abcdef') + expect(res.headers['transfer-encoding']).to.be.undefined + expect(res.headers['content-type']).to.be.undefined + expect(res.headers['content-length']).to.equal('16') + }) + }) + it('should allow POST request with ArrayBufferView (DataView) body', () => { const encoder = new TextEncoder() const url = `${base}inspect` diff --git a/test/node-fetch/request.js b/test/node-fetch/request.js index 87ba0f72f1c..86196946b47 100644 --- a/test/node-fetch/request.js +++ b/test/node-fetch/request.js @@ -225,34 +225,56 @@ describe('Request', () => { it('should support ArrayBuffer as body', () => { const encoder = new TextEncoder() + const body = encoder.encode('a=12345678901234').buffer const request = new Request(base, { method: 'POST', - body: encoder.encode('a=1').buffer + body }) + new Uint8Array(body)[0] = 0 return request.text().then(result => { - expect(result).to.equal('a=1') + expect(result).to.equal('a=12345678901234') }) }) it('should support Uint8Array as body', () => { const encoder = new TextEncoder() + const fullbuffer = encoder.encode('a=12345678901234').buffer + const body = new Uint8Array(fullbuffer, 2, 9) const request = new Request(base, { method: 'POST', - body: encoder.encode('a=1') + body }) + body[0] = 0 return request.text().then(result => { - expect(result).to.equal('a=1') + expect(result).to.equal('123456789') + }) + }) + + it('should support BigUint64Array as body', () => { + const encoder = new TextEncoder() + const fullbuffer = encoder.encode('a=12345678901234').buffer + const body = new BigUint64Array(fullbuffer, 8, 1) + const request = new Request(base, { + method: 'POST', + body + }) + body[0] = 0n + return request.text().then(result => { + expect(result).to.equal('78901234') }) }) it('should support DataView as body', () => { const encoder = new TextEncoder() + const fullbuffer = encoder.encode('a=12345678901234').buffer + const body = new Uint8Array(fullbuffer, 2, 9) const request = new Request(base, { method: 'POST', - body: new DataView(encoder.encode('a=1').buffer) + body }) + body[0] = 0 return request.text().then(result => { - expect(result).to.equal('a=1') + expect(result).to.equal('123456789') }) }) }) diff --git a/test/node-fetch/response.js b/test/node-fetch/response.js index b6dea5aec76..44f0c1ac437 100644 --- a/test/node-fetch/response.js +++ b/test/node-fetch/response.js @@ -161,9 +161,11 @@ describe('Response', () => { it('should support ArrayBuffer as body', () => { const encoder = new TextEncoder() - const res = new Response(encoder.encode('a=1')) + const fullbuffer = encoder.encode('a=12345678901234').buffer + const res = new Response(fullbuffer) + new Uint8Array(fullbuffer)[0] = 0 return res.text().then(result => { - expect(result).to.equal('a=1') + expect(result).to.equal('a=12345678901234') }) }) @@ -176,17 +178,34 @@ describe('Response', () => { it('should support Uint8Array as body', () => { const encoder = new TextEncoder() - const res = new Response(encoder.encode('a=1')) + const fullbuffer = encoder.encode('a=12345678901234').buffer + const body = new Uint8Array(fullbuffer, 2, 9) + const res = new Response(body) + body[0] = 0 return res.text().then(result => { - expect(result).to.equal('a=1') + expect(result).to.equal('123456789') + }) + }) + + it('should support BigUint64Array as body', () => { + const encoder = new TextEncoder() + const fullbuffer = encoder.encode('a=12345678901234').buffer + const body = new BigUint64Array(fullbuffer, 8, 1) + const res = new Response(body) + body[0] = 0n + return res.text().then(result => { + expect(result).to.equal('78901234') }) }) it('should support DataView as body', () => { const encoder = new TextEncoder() - const res = new Response(new DataView(encoder.encode('a=1').buffer)) + const fullbuffer = encoder.encode('a=12345678901234').buffer + const body = new Uint8Array(fullbuffer, 2, 9) + const res = new Response(body) + body[0] = 0 return res.text().then(result => { - expect(result).to.equal('a=1') + expect(result).to.equal('123456789') }) })