Socket
Socket
Sign inDemoInstall

undici

Package Overview
Dependencies
Maintainers
2
Versions
212
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

undici - npm Package Compare versions

Comparing version 2.0.1 to 2.0.2

test/headers-as-array.js

39

lib/core/client.js

@@ -159,6 +159,6 @@ 'use strict'

this[kResuming] = 0 // 0, idle, 1, scheduled, 2 resuming
this[kNeedDrain] = false
this[kNeedDrain] = 0 // 0, idle, 1, scheduled, 2 resuming
this[kResume] = () => {
if (this[kResuming] === 0) {
resume(this)
resume(this, true)
}

@@ -189,3 +189,3 @@ }

this[kPipelining] = value
resume(this)
resume(this, true)
}

@@ -254,3 +254,3 @@

} else {
resume(this)
resume(this, true)
}

@@ -634,8 +634,4 @@ } catch (err) {

!client.running &&
err.code !== 'ECONNRESET' &&
err.code !== 'ECONNREFUSED' &&
err.code !== 'EHOSTUNREACH' &&
err.code !== 'EHOSTDOWN' &&
err.code !== 'UND_ERR_SOCKET' &&
err.code !== 'UND_ERR_INFO'
err.code !== 'UND_ERR_INFO' &&
err.code !== 'UND_ERR_SOCKET'
) {

@@ -768,3 +764,8 @@ assert(client[kPendingIdx] === client[kRunningIdx])

function resume (client) {
function emitDrain (client) {
client[kNeedDrain] = 0
client.emit('drain')
}
function resume (client, sync) {
if (client[kResuming] === 2) {

@@ -775,3 +776,3 @@ return

client[kResuming] = 2
_resume(client)
_resume(client, sync)
client[kResuming] = 0

@@ -786,3 +787,3 @@

function _resume (client) {
function _resume (client, sync) {
while (true) {

@@ -818,5 +819,9 @@ if (client[kDestroyed]) {

if (!client.pending) {
if (client[kNeedDrain] && !client.busy) {
client[kNeedDrain] = false
client.emit('drain')
if (client[kNeedDrain] === 2 && !client.busy) {
if (sync) {
client[kNeedDrain] = 1
process.nextTick(emitDrain, client)
} else {
emitDrain(client)
}
continue

@@ -826,3 +831,3 @@ }

} else {
client[kNeedDrain] = true
client[kNeedDrain] = 2
}

@@ -829,0 +834,0 @@

@@ -72,55 +72,15 @@ 'use strict'

if (headers) {
if (Array.isArray(headers)) {
if (headers.length % 2 !== 0) {
throw new InvalidArgumentError('headers array must be even')
}
for (let i = 0; i < headers.length; i += 2) {
processHeader(this, headers[i], headers[i + 1])
}
} else if (headers && typeof headers === 'object') {
for (const [key, val] of Object.entries(headers)) {
if (typeof val === 'object') {
throw new InvalidArgumentError(`invalid ${key} header`)
} else if (val === undefined) {
continue
}
if (
this.host === null &&
key.length === 4 &&
key.toLowerCase() === 'host'
) {
this.host = val
this.headers += `${key}: ${val}\r\n`
} else if (
this.contentLength === null &&
key.length === 14 &&
key.toLowerCase() === 'content-length'
) {
this.contentLength = parseInt(val)
if (!Number.isFinite(this.contentLength)) {
throw new InvalidArgumentError('invalid content-length header')
}
} else if (
key.length === 17 &&
key.toLowerCase() === 'transfer-encoding'
) {
throw new InvalidArgumentError('invalid transfer-encoding header')
} else if (
key.length === 10 &&
key.toLowerCase() === 'connection'
) {
throw new InvalidArgumentError('invalid connection header')
} else if (
key.length === 10 &&
key.toLowerCase() === 'keep-alive'
) {
throw new InvalidArgumentError('invalid keep-alive header')
} else if (
key.length === 7 &&
key.toLowerCase() === 'upgrade'
) {
throw new InvalidArgumentError('invalid upgrade header')
} else if (
key.length === 6 &&
key.toLowerCase() === 'expect'
) {
throw new NotSupportedError('expect header not supported')
} else {
this.headers += `${key}: ${val}\r\n`
}
processHeader(this, key, val)
}
} else if (headers != null) {
throw new InvalidArgumentError('headers must be an object or an array')
}

@@ -198,2 +158,55 @@

function processHeader (request, key, val) {
if (typeof val === 'object') {
throw new InvalidArgumentError(`invalid ${key} header`)
} else if (val === undefined) {
return
}
if (
request.host === null &&
key.length === 4 &&
key.toLowerCase() === 'host'
) {
request.host = val
request.headers += `${key}: ${val}\r\n`
} else if (
request.contentLength === null &&
key.length === 14 &&
key.toLowerCase() === 'content-length'
) {
request.contentLength = parseInt(val)
if (!Number.isFinite(request.contentLength)) {
throw new InvalidArgumentError('invalid content-length header')
}
} else if (
key.length === 17 &&
key.toLowerCase() === 'transfer-encoding'
) {
throw new InvalidArgumentError('invalid transfer-encoding header')
} else if (
key.length === 10 &&
key.toLowerCase() === 'connection'
) {
throw new InvalidArgumentError('invalid connection header')
} else if (
key.length === 10 &&
key.toLowerCase() === 'keep-alive'
) {
throw new InvalidArgumentError('invalid keep-alive header')
} else if (
key.length === 7 &&
key.toLowerCase() === 'upgrade'
) {
throw new InvalidArgumentError('invalid upgrade header')
} else if (
key.length === 6 &&
key.toLowerCase() === 'expect'
) {
throw new NotSupportedError('expect header not supported')
} else {
request.headers += `${key}: ${val}\r\n`
}
}
function clearRequestTimeout (request) {

@@ -200,0 +213,0 @@ const { [kTimeout]: timeout } = request

{
"name": "undici",
"version": "2.0.1",
"version": "2.0.2",
"description": "An HTTP/1.1 client, written from scratch for Node.js",

@@ -5,0 +5,0 @@ "main": "index.js",

@@ -22,11 +22,11 @@ # undici

Machine: 2.8GHz AMD EPYC 7402P<br/>
Machine: AMD EPYC 7502P<br/>
Node 14
```
http - keepalive x 6,770 ops/sec ±7.70% (75 runs sampled)
undici - pipeline x 10,627 ops/sec ±5.88% (79 runs sampled)
undici - request x 10,902 ops/sec ±1.28% (85 runs sampled)
undici - stream x 20,144 ops/sec ±0.84% (86 runs sampled)
undici - dispatch x 20,295 ops/sec ±1.00% (83 runs sampled)
http - keepalive x 7,179 ops/sec ±2.32% (272 runs sampled)
undici - pipeline x 16,843 ops/sec ±0.98% (279 runs sampled)
undici - request x 18,738 ops/sec ±0.67% (276 runs sampled)
undici - stream x 21,215 ops/sec ±0.66% (278 runs sampled)
undici - dispatch x 23,540 ops/sec ±0.62% (278 runs sampled)
```

@@ -36,7 +36,7 @@

```
http - keepalive x 10,337 ops/sec ±6.17% (71 runs sampled)
undici - pipeline x 30,387 ops/sec ±1.37% (80 runs sampled)
undici - request x 40,117 ops/sec ±3.25% (77 runs sampled)
undici - stream x 40,543 ops/sec ±1.30% (80 runs sampled)
undici - dispatch x 50,434 ops/sec ±2.08% (77 runs sampled)
http - keepalive x 12,028 ops/sec ±2.60% (265 runs sampled)
undici - pipeline x 31,321 ops/sec ±0.77% (276 runs sampled)
undici - request x 36,612 ops/sec ±0.71% (277 runs sampled)
undici - stream x 41,291 ops/sec ±0.90% (268 runs sampled)
undici - dispatch x 47,319 ops/sec ±1.17% (263 runs sampled)
```

@@ -114,3 +114,3 @@

Default: `null`.
* `headers: Object|Null`, an object with header-value pairs.
* `headers: Object|Array|Null`, an object with header-value pairs or an array with header-value pairs bi-indexed (`['header1', 'value1', 'header2', 'value2']`).
Default: `null`.

@@ -139,2 +139,15 @@ * `signal: AbortController|EventEmitter|Null`

```
Or an array like this:
```js
[
'content-length', '123',
'content-type', 'text/plain',
'connection', 'keep-alive',
'host', 'mysite.com',
'accept', '*/*'
]
```
Keys are lowercased. Values are not modified.

@@ -141,0 +154,0 @@ If you don't specify a `host` header, it will be derived from the `url` of the client instance.

@@ -930,1 +930,13 @@ 'use strict'

})
test('socket errors', t => {
t.plan(2)
const client = new Client('http://localhost:5554')
t.tearDown(client.destroy.bind(client))
client.request({ path: '/', method: 'GET' }, (err, data) => {
t.ok(err)
t.is('ECONNREFUSED', err.code)
t.end()
})
})

@@ -9,4 +9,5 @@ 'use strict'

test('multiple reconnect', (t) => {
t.plan(3)
t.plan(5)
let n = 0
const clock = FakeTimers.install()

@@ -16,28 +17,33 @@ t.teardown(clock.uninstall.bind(clock))

const server = createServer((req, res) => {
res.end()
n === 0 ? res.destroy() : res.end('ok')
})
t.tearDown(server.close.bind(server))
const client = new Client('http://localhost:5555')
t.tearDown(client.destroy.bind(client))
server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.tearDown(client.destroy.bind(client))
client.request({ path: '/', method: 'GET' }, (err, data) => {
t.error(err)
data.body
.resume()
.on('end', () => {
client.request({ path: '/', method: 'GET' }, (err, data) => {
t.ok(err)
t.is(err.code, 'UND_ERR_SOCKET')
})
client.request({ path: '/', method: 'GET' }, (err, data) => {
t.error(err)
data.body
.resume()
.on('end', () => {
t.pass()
})
})
client.on('disconnect', () => {
if (++n === 1) {
t.pass()
}
process.nextTick(() => {
clock.tick(1000)
})
})
let n = 0
client.on('disconnect', () => {
if (++n === 1) {
t.pass()
server.listen(5555)
}
process.nextTick(() => {
clock.tick(1000)
})
})
})

@@ -7,3 +7,3 @@ 'use strict'

test('invalid headers', (t) => {
t.plan(10)
t.plan(11)

@@ -25,2 +25,10 @@ const client = new Client('http://localhost:3000')

method: 'GET',
headers: 1
}, (err, data) => {
t.ok(err instanceof errors.InvalidArgumentError)
})
client.request({
path: '/',
method: 'GET',
headers: {

@@ -27,0 +35,0 @@ 'transfer-encoding': 'chunked'

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc