mirror of
https://git.proxmox.com/git/package-rebuilds
synced 2025-08-22 14:27:59 +00:00
998 lines
24 KiB
JavaScript
998 lines
24 KiB
JavaScript
/* globals AbortController */
|
|
|
|
'use strict'
|
|
|
|
const { test } = require('tap')
|
|
const { Client, errors } = require('..')
|
|
const { createServer } = require('http')
|
|
const EE = require('events')
|
|
const { kConnect } = require('../lib/core/symbols')
|
|
const { Readable } = require('stream')
|
|
const net = require('net')
|
|
const { promisify } = require('util')
|
|
const { NotSupportedError } = require('../lib/core/errors')
|
|
const { nodeMajor } = require('../lib/core/util')
|
|
const { parseFormDataString } = require('./utils/formdata')
|
|
|
|
test('request dump', (t) => {
|
|
t.plan(3)
|
|
|
|
const server = createServer((req, res) => {
|
|
res.end('hello')
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
server.listen(0, () => {
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
let dumped = false
|
|
client.on('disconnect', () => {
|
|
t.equal(dumped, true)
|
|
})
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
}, (err, { body }) => {
|
|
t.error(err)
|
|
body.dump().then(() => {
|
|
dumped = true
|
|
t.pass()
|
|
})
|
|
})
|
|
})
|
|
})
|
|
|
|
test('request dump with abort signal', (t) => {
|
|
t.plan(2)
|
|
const server = createServer((req, res) => {
|
|
res.write('hello')
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
server.listen(0, () => {
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
}, (err, { body }) => {
|
|
t.error(err)
|
|
let ac
|
|
if (!global.AbortController) {
|
|
const { AbortController } = require('abort-controller')
|
|
ac = new AbortController()
|
|
} else {
|
|
ac = new AbortController()
|
|
}
|
|
body.dump({ signal: ac.signal }).catch((err) => {
|
|
t.equal(err.name, 'AbortError')
|
|
server.close()
|
|
})
|
|
ac.abort()
|
|
})
|
|
})
|
|
})
|
|
|
|
test('request hwm', (t) => {
|
|
t.plan(2)
|
|
const server = createServer((req, res) => {
|
|
res.write('hello')
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
server.listen(0, () => {
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
highWaterMark: 1000
|
|
}, (err, { body }) => {
|
|
t.error(err)
|
|
t.same(body.readableHighWaterMark, 1000)
|
|
body.dump()
|
|
})
|
|
})
|
|
})
|
|
|
|
test('request abort before headers', (t) => {
|
|
t.plan(6)
|
|
|
|
const signal = new EE()
|
|
const server = createServer((req, res) => {
|
|
res.end('hello')
|
|
signal.emit('abort')
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
server.listen(0, () => {
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
client[kConnect](() => {
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
signal
|
|
}, (err) => {
|
|
t.type(err, errors.RequestAbortedError)
|
|
t.equal(signal.listenerCount('abort'), 0)
|
|
})
|
|
t.equal(signal.listenerCount('abort'), 1)
|
|
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
signal
|
|
}, (err) => {
|
|
t.type(err, errors.RequestAbortedError)
|
|
t.equal(signal.listenerCount('abort'), 0)
|
|
})
|
|
t.equal(signal.listenerCount('abort'), 2)
|
|
})
|
|
})
|
|
})
|
|
|
|
test('request body destroyed on invalid callback', (t) => {
|
|
t.plan(1)
|
|
|
|
const server = createServer((req, res) => {
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
server.listen(0, () => {
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
const body = new Readable({
|
|
read () {}
|
|
})
|
|
try {
|
|
client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
body
|
|
}, null)
|
|
} catch (err) {
|
|
t.equal(body.destroyed, true)
|
|
}
|
|
})
|
|
})
|
|
|
|
test('trailers', (t) => {
|
|
t.plan(1)
|
|
|
|
const server = createServer((req, res) => {
|
|
res.writeHead(200, { Trailer: 'Content-MD5' })
|
|
res.addTrailers({ 'Content-MD5': 'test' })
|
|
res.end()
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
server.listen(0, async () => {
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.close.bind(client))
|
|
|
|
const { body, trailers } = await client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
})
|
|
|
|
body
|
|
.on('data', () => t.fail())
|
|
.on('end', () => {
|
|
t.strictSame(trailers, { 'content-md5': 'test' })
|
|
})
|
|
})
|
|
})
|
|
|
|
test('destroy socket abruptly', { skip: true }, async (t) => {
|
|
t.plan(2)
|
|
|
|
const server = net.createServer((socket) => {
|
|
const lines = [
|
|
'HTTP/1.1 200 OK',
|
|
'Date: Sat, 09 Oct 2010 14:28:02 GMT',
|
|
'Connection: close',
|
|
'',
|
|
'the body'
|
|
]
|
|
socket.end(lines.join('\r\n'))
|
|
|
|
// Unfortunately calling destroy synchronously might get us flaky results,
|
|
// therefore we delay it to the next event loop run.
|
|
setImmediate(socket.destroy.bind(socket))
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
await promisify(server.listen.bind(server))(0)
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.close.bind(client))
|
|
|
|
const { statusCode, body } = await client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
})
|
|
|
|
t.equal(statusCode, 200)
|
|
|
|
body.setEncoding('utf8')
|
|
|
|
let actual = ''
|
|
|
|
for await (const chunk of body) {
|
|
actual += chunk
|
|
}
|
|
|
|
t.equal(actual, 'the body')
|
|
})
|
|
|
|
test('destroy socket abruptly with keep-alive', { skip: true }, async (t) => {
|
|
t.plan(2)
|
|
|
|
const server = net.createServer((socket) => {
|
|
const lines = [
|
|
'HTTP/1.1 200 OK',
|
|
'Date: Sat, 09 Oct 2010 14:28:02 GMT',
|
|
'Connection: keep-alive',
|
|
'Content-Length: 42',
|
|
'',
|
|
'the body'
|
|
]
|
|
socket.end(lines.join('\r\n'))
|
|
|
|
// Unfortunately calling destroy synchronously might get us flaky results,
|
|
// therefore we delay it to the next event loop run.
|
|
setImmediate(socket.destroy.bind(socket))
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
await promisify(server.listen.bind(server))(0)
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.close.bind(client))
|
|
|
|
const { statusCode, body } = await client.request({
|
|
path: '/',
|
|
method: 'GET'
|
|
})
|
|
|
|
t.equal(statusCode, 200)
|
|
|
|
body.setEncoding('utf8')
|
|
|
|
try {
|
|
/* eslint-disable */
|
|
for await (const _ of body) {
|
|
// empty on purpose
|
|
}
|
|
/* eslint-enable */
|
|
t.fail('no error')
|
|
} catch (err) {
|
|
t.pass('error happened')
|
|
}
|
|
})
|
|
|
|
test('request json', (t) => {
|
|
t.plan(1)
|
|
|
|
const obj = { asd: true }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
t.strictSame(obj, await body.json())
|
|
})
|
|
})
|
|
|
|
test('request long multibyte json', (t) => {
|
|
t.plan(1)
|
|
|
|
const obj = { asd: 'あ'.repeat(100000) }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
t.strictSame(obj, await body.json())
|
|
})
|
|
})
|
|
|
|
test('request text', (t) => {
|
|
t.plan(1)
|
|
|
|
const obj = { asd: true }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
t.strictSame(JSON.stringify(obj), await body.text())
|
|
})
|
|
})
|
|
|
|
test('empty host header', (t) => {
|
|
t.plan(3)
|
|
|
|
const server = createServer((req, res) => {
|
|
res.end(req.headers.host)
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
server.listen(0, async () => {
|
|
const serverAddress = `localhost:${server.address().port}`
|
|
const client = new Client(`http://${serverAddress}`)
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
const getWithHost = async (host, wanted) => {
|
|
const { body } = await client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
headers: { host }
|
|
})
|
|
t.strictSame(await body.text(), wanted)
|
|
}
|
|
|
|
await getWithHost('test', 'test')
|
|
await getWithHost(undefined, serverAddress)
|
|
await getWithHost('', '')
|
|
})
|
|
})
|
|
|
|
test('request long multibyte text', (t) => {
|
|
t.plan(1)
|
|
|
|
const obj = { asd: 'あ'.repeat(100000) }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
t.strictSame(JSON.stringify(obj), await body.text())
|
|
})
|
|
})
|
|
|
|
test('request blob', { skip: nodeMajor < 16 }, (t) => {
|
|
t.plan(2)
|
|
|
|
const obj = { asd: true }
|
|
const server = createServer((req, res) => {
|
|
res.setHeader('Content-Type', 'application/json')
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
|
|
const blob = await body.blob()
|
|
t.strictSame(obj, JSON.parse(await blob.text()))
|
|
t.equal(blob.type, 'application/json')
|
|
})
|
|
})
|
|
|
|
test('request arrayBuffer', (t) => {
|
|
t.plan(2)
|
|
|
|
const obj = { asd: true }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
const ab = await body.arrayBuffer()
|
|
|
|
t.strictSame(Buffer.from(JSON.stringify(obj)), Buffer.from(ab))
|
|
t.ok(ab instanceof ArrayBuffer)
|
|
})
|
|
})
|
|
|
|
test('request body', { skip: nodeMajor < 16 }, (t) => {
|
|
t.plan(1)
|
|
|
|
const obj = { asd: true }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
|
|
let x = ''
|
|
for await (const chunk of body.body) {
|
|
x += Buffer.from(chunk)
|
|
}
|
|
t.strictSame(JSON.stringify(obj), x)
|
|
})
|
|
})
|
|
|
|
test('request post body no missing data', { skip: nodeMajor < 16 }, (t) => {
|
|
t.plan(2)
|
|
|
|
const server = createServer(async (req, res) => {
|
|
let ret = ''
|
|
for await (const chunk of req) {
|
|
ret += chunk
|
|
}
|
|
t.equal(ret, 'asd')
|
|
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: 'GET',
|
|
body: new Readable({
|
|
read () {
|
|
this.push('asd')
|
|
this.push(null)
|
|
}
|
|
}),
|
|
maxRedirections: 2
|
|
})
|
|
await body.text()
|
|
t.pass()
|
|
})
|
|
})
|
|
|
|
test('request post body no extra data handler', { skip: nodeMajor < 16 }, (t) => {
|
|
t.plan(3)
|
|
|
|
const server = createServer(async (req, res) => {
|
|
let ret = ''
|
|
for await (const chunk of req) {
|
|
ret += chunk
|
|
}
|
|
t.equal(ret, 'asd')
|
|
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 reqBody = new Readable({
|
|
read () {
|
|
this.push('asd')
|
|
this.push(null)
|
|
}
|
|
})
|
|
process.nextTick(() => {
|
|
t.equal(reqBody.listenerCount('data'), 0)
|
|
})
|
|
const { body } = await client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
body: reqBody,
|
|
maxRedirections: 0
|
|
})
|
|
await body.text()
|
|
t.pass()
|
|
})
|
|
})
|
|
|
|
test('request with onInfo callback', (t) => {
|
|
t.plan(3)
|
|
const infos = []
|
|
const server = createServer((req, res) => {
|
|
res.writeProcessing()
|
|
res.setHeader('Content-Type', 'application/json')
|
|
res.end(JSON.stringify({ foo: 'bar' }))
|
|
})
|
|
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))
|
|
|
|
await client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
onInfo: (x) => { infos.push(x) }
|
|
})
|
|
t.equal(infos.length, 1)
|
|
t.equal(infos[0].statusCode, 102)
|
|
t.pass()
|
|
})
|
|
})
|
|
|
|
test('request with onInfo callback but socket is destroyed before end of response', (t) => {
|
|
t.plan(5)
|
|
const infos = []
|
|
let response
|
|
const server = createServer((req, res) => {
|
|
response = res
|
|
res.writeProcessing()
|
|
})
|
|
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))
|
|
try {
|
|
await client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
onInfo: (x) => {
|
|
infos.push(x)
|
|
response.destroy()
|
|
}
|
|
})
|
|
t.error()
|
|
} catch (e) {
|
|
t.ok(e)
|
|
t.equal(e.message, 'other side closed')
|
|
}
|
|
t.equal(infos.length, 1)
|
|
t.equal(infos[0].statusCode, 102)
|
|
t.pass()
|
|
})
|
|
})
|
|
|
|
test('request onInfo callback headers parsing', async (t) => {
|
|
t.plan(4)
|
|
const infos = []
|
|
|
|
const server = net.createServer((socket) => {
|
|
const lines = [
|
|
'HTTP/1.1 103 Early Hints',
|
|
'Link: </style.css>; rel=preload; as=style',
|
|
'',
|
|
'HTTP/1.1 200 OK',
|
|
'Date: Sat, 09 Oct 2010 14:28:02 GMT',
|
|
'Connection: close',
|
|
'',
|
|
'the body'
|
|
]
|
|
socket.end(lines.join('\r\n'))
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
await promisify(server.listen.bind(server))(0)
|
|
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.close.bind(client))
|
|
|
|
const { body } = await client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
onInfo: (x) => { infos.push(x) }
|
|
})
|
|
await body.dump()
|
|
t.equal(infos.length, 1)
|
|
t.equal(infos[0].statusCode, 103)
|
|
t.same(infos[0].headers, { link: '</style.css>; rel=preload; as=style' })
|
|
t.pass()
|
|
})
|
|
|
|
test('request raw responseHeaders', async (t) => {
|
|
t.plan(4)
|
|
const infos = []
|
|
|
|
const server = net.createServer((socket) => {
|
|
const lines = [
|
|
'HTTP/1.1 103 Early Hints',
|
|
'Link: </style.css>; rel=preload; as=style',
|
|
'',
|
|
'HTTP/1.1 200 OK',
|
|
'Date: Sat, 09 Oct 2010 14:28:02 GMT',
|
|
'Connection: close',
|
|
'',
|
|
'the body'
|
|
]
|
|
socket.end(lines.join('\r\n'))
|
|
})
|
|
t.teardown(server.close.bind(server))
|
|
|
|
await promisify(server.listen.bind(server))(0)
|
|
|
|
const client = new Client(`http://localhost:${server.address().port}`)
|
|
t.teardown(client.close.bind(client))
|
|
|
|
const { body, headers } = await client.request({
|
|
path: '/',
|
|
method: 'GET',
|
|
responseHeaders: 'raw',
|
|
onInfo: (x) => { infos.push(x) }
|
|
})
|
|
await body.dump()
|
|
t.equal(infos.length, 1)
|
|
t.same(infos[0].headers, ['Link', '</style.css>; rel=preload; as=style'])
|
|
t.same(headers, ['Date', 'Sat, 09 Oct 2010 14:28:02 GMT', 'Connection', 'close'])
|
|
t.pass()
|
|
})
|
|
|
|
test('request formData', { skip: nodeMajor < 16 }, (t) => {
|
|
t.plan(1)
|
|
|
|
const obj = { asd: true }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
|
|
try {
|
|
await body.formData()
|
|
t.fail('should throw NotSupportedError')
|
|
} catch (error) {
|
|
t.ok(error instanceof NotSupportedError)
|
|
}
|
|
})
|
|
})
|
|
|
|
test('request text2', (t) => {
|
|
t.plan(2)
|
|
|
|
const obj = { asd: true }
|
|
const server = createServer((req, res) => {
|
|
res.end(JSON.stringify(obj))
|
|
})
|
|
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: 'GET'
|
|
})
|
|
const p = body.text()
|
|
let ret = ''
|
|
body.on('data', chunk => {
|
|
ret += chunk
|
|
}).on('end', () => {
|
|
t.equal(JSON.stringify(obj), ret)
|
|
})
|
|
t.strictSame(JSON.stringify(obj), await p)
|
|
})
|
|
})
|
|
|
|
test('request with FormData body', { skip: nodeMajor < 16 }, (t) => {
|
|
const { FormData } = require('../')
|
|
const { Blob } = require('buffer')
|
|
|
|
const fd = new FormData()
|
|
fd.set('key', 'value')
|
|
fd.set('file', new Blob(['Hello, world!']), 'hello_world.txt')
|
|
|
|
const server = createServer(async (req, res) => {
|
|
const contentType = req.headers['content-type']
|
|
// ensure we received a multipart/form-data header
|
|
t.ok(/^multipart\/form-data; boundary=-+formdata-undici-0\d+$/.test(contentType))
|
|
|
|
const chunks = []
|
|
|
|
for await (const chunk of req) {
|
|
chunks.push(chunk)
|
|
}
|
|
|
|
const { fileMap, fields } = await parseFormDataString(
|
|
Buffer.concat(chunks),
|
|
contentType
|
|
)
|
|
|
|
t.same(fields[0], { key: 'key', value: 'value' })
|
|
t.ok(fileMap.has('file'))
|
|
t.equal(fileMap.get('file').data.toString(), 'Hello, world!')
|
|
t.same(fileMap.get('file').info, {
|
|
filename: 'hello_world.txt',
|
|
encoding: '7bit',
|
|
mimeType: 'application/octet-stream'
|
|
})
|
|
|
|
return 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))
|
|
|
|
await client.request({
|
|
path: '/',
|
|
method: 'POST',
|
|
body: fd
|
|
})
|
|
|
|
t.end()
|
|
})
|
|
})
|
|
|
|
test('request with FormData body on node < 16', { skip: nodeMajor >= 16 }, async (t) => {
|
|
t.plan(1)
|
|
|
|
// a FormData polyfill, for example
|
|
class FormData {}
|
|
|
|
const fd = new FormData()
|
|
|
|
const client = new Client('http://localhost:3000')
|
|
t.teardown(client.destroy.bind(client))
|
|
|
|
await t.rejects(client.request({
|
|
path: '/',
|
|
method: 'POST',
|
|
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()
|
|
})
|
|
})
|