Skip to content

Commit 8549a94

Browse files
fix: support ArrayBufferView and ArrayBuffer as body (#1584)
* fix: support `ArrayBufferView` and `ArrayBuffer` as body * test: ArrayBufferView as Request.body
1 parent e46d8bf commit 8549a94

File tree

4 files changed

+76
-19
lines changed

4 files changed

+76
-19
lines changed

lib/fetch/body.js

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,16 +57,16 @@ function extractBody (object, keepalive = false) {
5757

5858
// Set Content-Type to `application/x-www-form-urlencoded;charset=UTF-8`.
5959
contentType = 'application/x-www-form-urlencoded;charset=UTF-8'
60-
} else if (isArrayBuffer(object) || ArrayBuffer.isView(object)) {
61-
// BufferSource
60+
} else if (isArrayBuffer(object)) {
61+
// BufferSource/ArrayBuffer
6262

63-
if (object instanceof DataView) {
64-
// TODO: Blob doesn't seem to work with DataView?
65-
object = object.buffer
66-
}
63+
// Set source to a copy of the bytes held by object.
64+
source = new Uint8Array(object.slice())
65+
} else if (ArrayBuffer.isView(object)) {
66+
// BufferSource/ArrayBufferView
6767

6868
// Set source to a copy of the bytes held by object.
69-
source = new Uint8Array(object)
69+
source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength))
7070
} else if (util.isFormDataLike(object)) {
7171
const boundary = '----formdata-undici-' + Math.random()
7272
const prefix = `--${boundary}\r\nContent-Disposition: form-data`

test/node-fetch/main.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,6 +1032,22 @@ describe('node-fetch', () => {
10321032
})
10331033
})
10341034

1035+
it('should allow POST request with ArrayBufferView (BigUint64Array) body', () => {
1036+
const encoder = new TextEncoder()
1037+
const url = `${base}inspect`
1038+
const options = {
1039+
method: 'POST',
1040+
body: new BigUint64Array(encoder.encode('0123456789abcdef').buffer)
1041+
}
1042+
return fetch(url, options).then(res => res.json()).then(res => {
1043+
expect(res.method).to.equal('POST')
1044+
expect(res.body).to.equal('0123456789abcdef')
1045+
expect(res.headers['transfer-encoding']).to.be.undefined
1046+
expect(res.headers['content-type']).to.be.undefined
1047+
expect(res.headers['content-length']).to.equal('16')
1048+
})
1049+
})
1050+
10351051
it('should allow POST request with ArrayBufferView (DataView) body', () => {
10361052
const encoder = new TextEncoder()
10371053
const url = `${base}inspect`

test/node-fetch/request.js

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,34 +225,56 @@ describe('Request', () => {
225225

226226
it('should support ArrayBuffer as body', () => {
227227
const encoder = new TextEncoder()
228+
const body = encoder.encode('a=12345678901234').buffer
228229
const request = new Request(base, {
229230
method: 'POST',
230-
body: encoder.encode('a=1').buffer
231+
body
231232
})
233+
new Uint8Array(body)[0] = 0
232234
return request.text().then(result => {
233-
expect(result).to.equal('a=1')
235+
expect(result).to.equal('a=12345678901234')
234236
})
235237
})
236238

237239
it('should support Uint8Array as body', () => {
238240
const encoder = new TextEncoder()
241+
const fullbuffer = encoder.encode('a=12345678901234').buffer
242+
const body = new Uint8Array(fullbuffer, 2, 9)
239243
const request = new Request(base, {
240244
method: 'POST',
241-
body: encoder.encode('a=1')
245+
body
242246
})
247+
body[0] = 0
243248
return request.text().then(result => {
244-
expect(result).to.equal('a=1')
249+
expect(result).to.equal('123456789')
250+
})
251+
})
252+
253+
it('should support BigUint64Array as body', () => {
254+
const encoder = new TextEncoder()
255+
const fullbuffer = encoder.encode('a=12345678901234').buffer
256+
const body = new BigUint64Array(fullbuffer, 8, 1)
257+
const request = new Request(base, {
258+
method: 'POST',
259+
body
260+
})
261+
body[0] = 0n
262+
return request.text().then(result => {
263+
expect(result).to.equal('78901234')
245264
})
246265
})
247266

248267
it('should support DataView as body', () => {
249268
const encoder = new TextEncoder()
269+
const fullbuffer = encoder.encode('a=12345678901234').buffer
270+
const body = new Uint8Array(fullbuffer, 2, 9)
250271
const request = new Request(base, {
251272
method: 'POST',
252-
body: new DataView(encoder.encode('a=1').buffer)
273+
body
253274
})
275+
body[0] = 0
254276
return request.text().then(result => {
255-
expect(result).to.equal('a=1')
277+
expect(result).to.equal('123456789')
256278
})
257279
})
258280
})

test/node-fetch/response.js

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -161,9 +161,11 @@ describe('Response', () => {
161161

162162
it('should support ArrayBuffer as body', () => {
163163
const encoder = new TextEncoder()
164-
const res = new Response(encoder.encode('a=1'))
164+
const fullbuffer = encoder.encode('a=12345678901234').buffer
165+
const res = new Response(fullbuffer)
166+
new Uint8Array(fullbuffer)[0] = 0
165167
return res.text().then(result => {
166-
expect(result).to.equal('a=1')
168+
expect(result).to.equal('a=12345678901234')
167169
})
168170
})
169171

@@ -176,17 +178,34 @@ describe('Response', () => {
176178

177179
it('should support Uint8Array as body', () => {
178180
const encoder = new TextEncoder()
179-
const res = new Response(encoder.encode('a=1'))
181+
const fullbuffer = encoder.encode('a=12345678901234').buffer
182+
const body = new Uint8Array(fullbuffer, 2, 9)
183+
const res = new Response(body)
184+
body[0] = 0
180185
return res.text().then(result => {
181-
expect(result).to.equal('a=1')
186+
expect(result).to.equal('123456789')
187+
})
188+
})
189+
190+
it('should support BigUint64Array as body', () => {
191+
const encoder = new TextEncoder()
192+
const fullbuffer = encoder.encode('a=12345678901234').buffer
193+
const body = new BigUint64Array(fullbuffer, 8, 1)
194+
const res = new Response(body)
195+
body[0] = 0n
196+
return res.text().then(result => {
197+
expect(result).to.equal('78901234')
182198
})
183199
})
184200

185201
it('should support DataView as body', () => {
186202
const encoder = new TextEncoder()
187-
const res = new Response(new DataView(encoder.encode('a=1').buffer))
203+
const fullbuffer = encoder.encode('a=12345678901234').buffer
204+
const body = new Uint8Array(fullbuffer, 2, 9)
205+
const res = new Response(body)
206+
body[0] = 0
188207
return res.text().then(result => {
189-
expect(result).to.equal('a=1')
208+
expect(result).to.equal('123456789')
190209
})
191210
})
192211

0 commit comments

Comments
 (0)