Skip to content

Commit

Permalink
fix: support TypedArray and DataView as Request body (#1472)
Browse files Browse the repository at this point in the history
* fix: support `TypedArray` and `DataView` as Request body

* test: test `TypedArray` and `DataView` as Request body
  • Loading branch information
LiviaMedeiros committed Jun 1, 2022
1 parent f8ed1d4 commit 48c03b6
Show file tree
Hide file tree
Showing 2 changed files with 213 additions and 5 deletions.
9 changes: 4 additions & 5 deletions lib/core/request.js
Expand Up @@ -80,13 +80,12 @@ class Request {
this.body = null
} else if (util.isStream(body)) {
this.body = body
} else if (body instanceof DataView) {
// TODO: Why is DataView special?
this.body = body.buffer.byteLength ? Buffer.from(body.buffer) : null
} else if (body instanceof ArrayBuffer || ArrayBuffer.isView(body)) {
this.body = body.byteLength ? Buffer.from(body) : null
} else if (util.isBuffer(body)) {
this.body = body.byteLength ? body : null
} else if (ArrayBuffer.isView(body)) {
this.body = body.buffer.byteLength ? Buffer.from(body.buffer, body.byteOffset, body.byteLength) : null
} else if (body instanceof ArrayBuffer) {
this.body = body.byteLength ? Buffer.from(body) : null
} else if (typeof body === 'string') {
this.body = body.length ? Buffer.from(body) : null
} else if (util.isFormDataLike(body) || util.isIterable(body) || util.isBlobLike(body)) {
Expand Down
209 changes: 209 additions & 0 deletions test/client-request.js
Expand Up @@ -727,3 +727,212 @@ test('request with FormData body on node < 16', { skip: nodeMajor >= 16 }, async
body: fd
}), errors.InvalidArgumentError)
})

test('request post body Buffer from string', (t) => {
t.plan(2)
const requestBody = Buffer.from('abcdefghijklmnopqrstuvwxyz')

const server = createServer(async (req, res) => {
let ret = ''
for await (const chunk of req) {
ret += chunk
}
t.equal(ret, 'abcdefghijklmnopqrstuvwxyz')
res.end()
})
t.teardown(server.close.bind(server))

server.listen(0, async () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.teardown(client.destroy.bind(client))

const { body } = await client.request({
path: '/',
method: 'POST',
body: requestBody,
maxRedirections: 2
})
await body.text()
t.pass()
})
})

test('request post body Buffer from buffer', (t) => {
t.plan(2)
const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz')
const requestBody = Buffer.from(fullBuffer.buffer, 8, 16)

const server = createServer(async (req, res) => {
let ret = ''
for await (const chunk of req) {
ret += chunk
}
t.equal(ret, 'ijklmnopqrstuvwx')
res.end()
})
t.teardown(server.close.bind(server))

server.listen(0, async () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.teardown(client.destroy.bind(client))

const { body } = await client.request({
path: '/',
method: 'POST',
body: requestBody,
maxRedirections: 2
})
await body.text()
t.pass()
})
})

test('request post body Uint8Array', (t) => {
t.plan(2)
const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz')
const requestBody = new Uint8Array(fullBuffer.buffer, 8, 16)

const server = createServer(async (req, res) => {
let ret = ''
for await (const chunk of req) {
ret += chunk
}
t.equal(ret, 'ijklmnopqrstuvwx')
res.end()
})
t.teardown(server.close.bind(server))

server.listen(0, async () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.teardown(client.destroy.bind(client))

const { body } = await client.request({
path: '/',
method: 'POST',
body: requestBody,
maxRedirections: 2
})
await body.text()
t.pass()
})
})

test('request post body Uint32Array', (t) => {
t.plan(2)
const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz')
const requestBody = new Uint32Array(fullBuffer.buffer, 8, 4)

const server = createServer(async (req, res) => {
let ret = ''
for await (const chunk of req) {
ret += chunk
}
t.equal(ret, 'ijklmnopqrstuvwx')
res.end()
})
t.teardown(server.close.bind(server))

server.listen(0, async () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.teardown(client.destroy.bind(client))

const { body } = await client.request({
path: '/',
method: 'POST',
body: requestBody,
maxRedirections: 2
})
await body.text()
t.pass()
})
})

test('request post body Float64Array', (t) => {
t.plan(2)
const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz')
const requestBody = new Float64Array(fullBuffer.buffer, 8, 2)

const server = createServer(async (req, res) => {
let ret = ''
for await (const chunk of req) {
ret += chunk
}
t.equal(ret, 'ijklmnopqrstuvwx')
res.end()
})
t.teardown(server.close.bind(server))

server.listen(0, async () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.teardown(client.destroy.bind(client))

const { body } = await client.request({
path: '/',
method: 'POST',
body: requestBody,
maxRedirections: 2
})
await body.text()
t.pass()
})
})

test('request post body BigUint64Array', (t) => {
t.plan(2)
const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz')
const requestBody = new BigUint64Array(fullBuffer.buffer, 8, 2)

const server = createServer(async (req, res) => {
let ret = ''
for await (const chunk of req) {
ret += chunk
}
t.equal(ret, 'ijklmnopqrstuvwx')
res.end()
})
t.teardown(server.close.bind(server))

server.listen(0, async () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.teardown(client.destroy.bind(client))

const { body } = await client.request({
path: '/',
method: 'POST',
body: requestBody,
maxRedirections: 2
})
await body.text()
t.pass()
})
})

test('request post body DataView', (t) => {
t.plan(2)
const fullBuffer = new TextEncoder().encode('abcdefghijklmnopqrstuvwxyz')
const requestBody = new DataView(fullBuffer.buffer, 8, 16)

const server = createServer(async (req, res) => {
let ret = ''
for await (const chunk of req) {
ret += chunk
}
t.equal(ret, 'ijklmnopqrstuvwx')
res.end()
})
t.teardown(server.close.bind(server))

server.listen(0, async () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.teardown(client.destroy.bind(client))

const { body } = await client.request({
path: '/',
method: 'POST',
body: requestBody,
maxRedirections: 2
})
await body.text()
t.pass()
})
})

0 comments on commit 48c03b6

Please sign in to comment.