Socket
Socket
Sign inDemoInstall

undici

Package Overview
Dependencies
Maintainers
2
Versions
211
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 3.3.1 to 3.3.2

7

lib/agent.js
'use strict'
const { InvalidArgumentError, InvalidReturnValueError } = require('./core/errors')
const Pool = require('./pool')
const Client = require('./core/client')
const util = require('./core/util')

@@ -22,3 +23,3 @@ const { kAgentOpts, kAgentCache } = require('./core/symbols')

function onDisconnect () {
if (this.connected === 0 && this.pending === 0) {
if (this.connected === 0 && this.size === 0) {
this.off('disconnect', onDisconnect)

@@ -30,3 +31,5 @@ self[kAgentCache].delete(origin)

if (!pool) {
pool = new Pool(origin, self[kAgentOpts])
pool = self[kAgentOpts] && self[kAgentOpts].connections === 1
? new Client(origin, self[kAgentOpts])
: new Pool(origin, self[kAgentOpts])
pool.on('disconnect', onDisconnect)

@@ -33,0 +36,0 @@ self[kAgentCache].set(origin, pool)

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

!this[kSocket].destroyed
)
) ? 1 : 0
}

@@ -745,3 +745,3 @@

client.emit('connect')
client.emit('connect', client)
resume(client)

@@ -825,3 +825,3 @@ }

client.emit('disconnect', err)
client.emit('disconnect', client, err)
}

@@ -828,0 +828,0 @@

@@ -147,3 +147,4 @@ 'use strict'

return this[kHandler].onError(err)
// Ensure all queued handlers are invoked before calling onError.
util.queueMicrotask(() => this[kHandler].onError(err))
}

@@ -150,0 +151,0 @@ }

@@ -169,3 +169,6 @@ 'use strict'

bodyLength,
isBuffer
isBuffer,
queueMicrotask: global.queueMicrotask || (cb => Promise.resolve()
.then(cb)
.catch(err => setTimeout(() => { throw err }, 0)))
}

@@ -62,24 +62,22 @@ 'use strict'

if (queue.isEmpty()) {
if (pool[kNeedDrain]) {
pool[kNeedDrain] = false
pool.emit('drain')
}
if (pool[kNeedDrain] && !this.busy) {
pool[kNeedDrain] = false
pool.emit('drain')
}
if (pool[kClosedResolve]) {
Promise
.all(pool[kClients].map(c => c.close()))
.then(pool[kClosedResolve])
}
if (pool[kClosedResolve] && queue.isEmpty()) {
Promise
.all(pool[kClients].map(c => c.close()))
.then(pool[kClosedResolve])
}
}
this[kOnConnect] = function onConnect () {
this[kOnConnect] = function onConnect (client) {
pool[kConnected]++
pool.emit('connect', this)
pool.emit('connect', client)
}
this[kOnDisconnect] = function onDisconnect (err) {
this[kOnDisconnect] = function onDisconnect (client, err) {
pool[kConnected]--
pool.emit('disconnect', this, err)
pool.emit('disconnect', client, err)
}

@@ -97,13 +95,48 @@ }

get busy () {
return this[kPending] > 0
if (this[kPending] > 0) {
return true
}
if (this[kConnections] && this[kClients].length === this[kConnections]) {
for (const { busy } of this[kClients]) {
if (!busy) {
return false
}
}
return true
}
return false
}
get pending () {
return this[kPending]
let ret = this[kPending]
for (const { pending } of this[kClients]) {
ret += pending
}
return ret
}
// TODO: get running () {}
get running () {
let ret = 0
// TODO: get size () {}
for (const { running } of this[kClients]) {
ret += running
}
return ret
}
get size () {
let ret = this[kPending]
for (const { size } of this[kClients]) {
ret += size
}
return ret
}
get destroyed () {

@@ -146,2 +179,5 @@ return this[kDestroyed]

client.dispatch(opts, handler)
if (client.busy && this.busy) {
this[kNeedDrain] = true
}
}

@@ -148,0 +184,0 @@ } catch (err) {

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

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

@@ -66,2 +66,4 @@ # undici

Requests are not guaranteeed to be dispatched in order of invocation.
`url` can be a string or a [`URL`](https://nodejs.org/api/url.html#url_class_url) object.

@@ -456,2 +458,4 @@ It should only include the protocol, hostname, and port.

Multiple handler methods may be invoked in the same tick.
Options:

@@ -532,5 +536,5 @@

#### `client.connected: Boolean`
#### `client.connected: Number`
True if the client has an active connection. The client will lazily
Thruthy if the client has an active connection. The client will lazily
create a connection when it receives a request and will destroy it

@@ -559,7 +563,9 @@ if there is no activity for the duration of the `timeout` value.

* `'connect'`, emitted when a socket has been created and
connected. The client will connect once `client.size > 0`.
connected. The first argument is the `Client` instance.
The client will connect once `client.size > 0`.
* `'disconnect'`, emitted when socket has disconnected. The
first argument of the event is the error which caused the
socket to disconnect. The client will reconnect if or once
socket to disconnect. The second argument is the
`Client` instance. The client will reconnect if or once
`client.size > 0`.

@@ -571,3 +577,6 @@

A pool of [`Client`][] connected to the same upstream target.
Implements the same api as [`Client`][].
Requests are not guaranteeed to be dispatched in order of invocation.
Options:

@@ -579,74 +588,2 @@

`Pool` does not guarantee that requests are dispatched in
order of invocation.
#### `pool.url: URL`
Returns url passed to `undici.Pool(url, opts)`.
#### `pool.connected: Integer`
Number of active connections in pool.
#### `pool.pending: Number`
Number of queued requests.
#### `pool.busy: Boolean`
True if pool is saturated or blocked. Indicates whether dispatching
further requests is meaningful.
#### `pool.closed: Boolean`
True after `pool.close()` has been called.
#### `pool.destroyed: Boolean`
True after `pool.destroyed()` has been called or `pool.close()` has been
called and the client shutdown has completed.
#### `pool.request(opts[, callback]): Promise|Void`
Calls [`client.request(opts, callback)`][request] on one of the clients.
#### `pool.stream(opts, factory[, callback]): Promise|Void`
Calls [`client.stream(opts, factory, callback)`][stream] on one of the clients.
#### `pool.pipeline(opts, handler): Duplex`
Calls [`client.pipeline(opts, handler)`][pipeline] on one of the clients.
#### `pool.upgrade(opts[, callback]): Promise|Void`
Calls [`client.upgrade(opts, callback)`][upgrade] on one of the clients.
#### `pool.connect(opts[, callback]): Promise|Void`
Calls [`client.connect(opts, callback)`][connect] on one of the clients.
#### `pool.dispatch(opts, handler): Void`
Calls [`client.dispatch(opts, handler)`][dispatch] on one of the clients.
#### `pool.close([callback]): Promise|Void`
Calls [`client.close(callback)`](#close) on all the clients.
#### `pool.destroy([err][, callback]): Promise|Void`
Calls [`client.destroy(err, callback)`](#destroy) on all the clients.
#### Events
* `'drain'`, emitted when pool is no longer fully
saturated.
* `'connect'`, emitted when a client has connected, the `Client`
instance is passed as argument.
* `'disconnect'`, emitted when a client has disconnected. The first argument is the
`Client` instance, the second is the the error that caused the disconnection.
<a name='agent'></a>

@@ -653,0 +590,0 @@ ### `new undici.Agent(opts)`

@@ -6,2 +6,3 @@ 'use strict'

const http = require('http')
const { PassThrough } = require('stream')

@@ -601,1 +602,43 @@ test('dispatch invalid opts', (t) => {

})
test('ensure promise callback runs before onError', t => {
t.plan(2)
const server = http.createServer((req, res) => {
res.end()
})
t.tearDown(server.close.bind(server))
server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`)
t.tearDown(client.close.bind(client))
const stream = new PassThrough()
new Promise(resolve => client.dispatch({
path: '/',
method: 'POST',
body: Buffer.alloc(1e6)
}, {
onConnect () {
},
onHeaders () {
resolve()
},
onData () {
},
onComplete () {
throw new Error()
},
onError (err) {
t.ok(err)
stream.destroy(err)
}
})).then(() => {
stream.on('error', (err) => {
t.ok(err)
})
})
})
})

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

t.ok(err instanceof errors.RequestAbortedError)
t.strictEqual(signal.listenerCount('abort'), 0)
t.strictEqual(signal.listenerCount('abort'), 1)
})

@@ -44,0 +44,0 @@ t.strictEqual(signal.listenerCount('abort'), 2)

@@ -962,1 +962,35 @@ 'use strict'

})
test('connected', (t) => {
t.plan(5)
const server = createServer((req, res) => {
req.pipe(res)
})
t.tearDown(server.close.bind(server))
server.listen(0, () => {
const client = new Client(`http://localhost:${server.address().port}`, {
pipelining: 1
})
t.tearDown(client.close.bind(client))
client.on('connect', self => {
t.strictEqual(client, self)
})
client.on('disconnect', self => {
t.strictEqual(client, self)
})
t.strictEqual(client.connected, 0)
client[kConnect](() => {
client.request({
path: '/',
method: 'GET'
}, (err) => {
t.error(err)
})
t.strictEqual(client.connected, 1)
})
})
})

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

client.on('disconnect', (err) => {
client.on('disconnect', (client, err) => {
t.strictEqual(err.code, 'UND_ERR_SOCKET')

@@ -262,0 +262,0 @@ })

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

test('busy', (t) => {
t.plan(8 * 8 + 2 + 1)
t.plan(8 * 10 + 2 + 1)

@@ -383,4 +383,6 @@ const server = createServer((req, res) => {

})
t.strictEqual(client.pending, Math.max(n - 2, 0))
t.strictEqual(client.busy, n > 2)
t.strictEqual(client.pending, n)
t.strictEqual(client.busy, n >= 2)
t.strictEqual(client.size, n)
t.strictEqual(client.running, 0)
}

@@ -387,0 +389,0 @@ })

@@ -11,2 +11,7 @@ import { expectAssignable } from 'tsd'

expectAssignable<errors.UndiciError>(new errors.BodyTimeoutError())
expectAssignable<errors.BodyTimeoutError>(new errors.BodyTimeoutError())
expectAssignable<'BodyTimeoutError'>(new errors.BodyTimeoutError().name)
expectAssignable<'UND_ERR_BODY_TIMEOUT'>(new errors.BodyTimeoutError().code)
expectAssignable<errors.UndiciError>(new errors.SocketTimeoutError())

@@ -13,0 +18,0 @@ expectAssignable<errors.SocketTimeoutError>(new errors.SocketTimeoutError())

@@ -12,2 +12,8 @@ export = Errors

/** A body exceeds the `bodyTimeout` option. */
export class BodyTimeoutError extends UndiciError {
name: 'BodyTimeoutError';
code: 'UND_ERR_BODY_TIMEOUT';
}
/** A socket exceeds the `socketTimeout` option. */

@@ -14,0 +20,0 @@ export class SocketTimeoutError extends UndiciError {

SocketSocket SOC 2 Logo

Product

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

Packages

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc