A basic HTTP/1.1 client mapped on top of a single TCP/TLS connection. When the server supports HTTP/2 and selects it during ALPN negotiation, the same connection is used for HTTP/2. Pipelining is disabled by default.
Client extends Dispatcher and is the lowest-level dispatcher in undici:
it manages exactly one origin over one connection. For pooling across multiple
connections use Pool, and for routing across multiple origins use
Agent. Requests are not guaranteed to be dispatched in the order in which
they are invoked.
import { Client } from 'undici'
const client = new Client('http://localhost:3000')
const { statusCode, body } = await client.request({ path: '/', method: 'GET' })class Client extends Dispatchernew Client(url, options?): Client<Object>0
to disable it entirely.
Default:
300e3
.0
to disable it entirely.
Default:
300e3
.0
to disable it entirely.
Default:
10e3
.4e3
.keepAliveTimeout
,
in milliseconds, when overridden by
keep-alive
hints from the server.
Default:
600e3
.keepAliveTimeout
,
to account for timing inaccuracies caused by e.g. transport latency.
Default:
2e3
.--max-http-header-size
or
16384
(16 KiB).-1
to disable it.
Default:
-1
.0
to disable this
limit.
Default:
null
.1
when the remote server is trusted. Set to
0
to disable
keep-alive connections. Has no effect once HTTP/2 is negotiated; see
maxConcurrentStreams
for the HTTP/2 dispatch ceiling.
Default:
1
.<Object>
|
<Function>
|
<null>ConnectOptions
object passed to the built-in
buildConnector
(every [
tls.connect()
][] option is accepted, plus the
fields below), or a custom connector function with the signature
(options, callback)
.
Default:
null
.null
.0
to disable TLS session caching.
Default:
100
.<boolean>content-length
header does not match the length of the request body.
Disabling this exposes the application to HTTP request smuggling; only do so
in controlled environments where the request source is fully trusted.
Default:
true
.<boolean>false
.<number>autoSelectFamily
is enabled.
Default:
250
.<boolean>true
.<boolean>false
.<number>pipelining
,
which is HTTP/1.1 only — is the ceiling used to dispatch in-flight requests.
It may be overridden by the server's
SETTINGS_MAX_CONCURRENT_STREAMS
frame.
Default:
100
.<number>SETTINGS_INITIAL_WINDOW_SIZE
). Must be a positive integer.
Default:
262144
.<number>ClientHttp2Session.setLocalWindowSize()
. Must be a
positive integer.
Default:
524288
.<number>0
to disable PING frames. Applies only to HTTP/2
connections and emits a
ping
event on the client.
Default:
60e3
.<Object><number>0
to disable the limit.
Default:
131072
.<number>permessage-deflate
) messages. Set to
0
to
disable the limit.
Default:
134217728
.<Client>Instantiating a Client does not open a connection; the connection is
established lazily once a request is queued. Call client.connect() to connect
eagerly.
Notes about HTTP/2:
- Pseudo headers (
:path,:method,:scheme,:authority) are attached automatically and overwrite any user-provided values.- The server must support HTTP/2 and select it during ALPN negotiation, and must not give HTTP/1.1 a higher priority than HTTP/2.
PUSHframes are not supported.
import { Client } from 'undici'
const client = new Client('http://localhost:3000')When a connector function is provided, undici wraps it to automatically inject
socketPath and allowH2 into the options argument when those values are set
on the client. See Connector for details on building custom connectors.
client.close(callback?): voidImplements [dispatcher.close([callback])][]. Closes the client gracefully,
waiting for enqueued requests to complete before resolving.
client.destroy(error?, callback?): voidImplements [dispatcher.destroy([error[, callback]])][]. Destroys the client
abruptly, aborting all pending and running requests, and waits until the socket
is closed before invoking callback (or resolving the returned promise).
client.connect(options, callback?): Promise | void<Object>dispatcher.connect()
][] except that
origin
is omitted because the client
is bound to a single origin.<Function><Promise>
|
<void>callback
is not provided.Starts a connection to the client's origin and tunnels a connection through it,
as defined by [dispatcher.connect()][].
client.dispatch(options, handlers): voidImplements [dispatcher.dispatch(options, handler)][]. This is the lowest-level
API used by all other request methods; prefer client.request() for most use
cases.
client.pipeline(options, handler): voidSee [dispatcher.pipeline(options, handler)][]. Sends a request and returns a
<Duplex> stream that the request body is written to and the response body is
read from.
client.request(options, callback?): Promise | void<Object><Function><Promise>
|
<void>callback
is not provided.See [dispatcher.request(options[, callback])][]. Performs an HTTP request and
returns its status code, headers, trailers, and a readable body stream.
import { Client } from 'undici'
const client = new Client('http://localhost:3000')
const { statusCode, headers, body } = await client.request({
path: '/',
method: 'GET'
})
console.log(statusCode)
for await (const chunk of body) {
console.log(chunk.toString())
}client.stream(options, factory, callback?): Promise | void<Object><Function><Writable>
the response body is piped into.<Function><Promise>
|
<void>callback
is not provided.See [dispatcher.stream(options, factory[, callback])][]. A faster alternative
to client.request() when the destination of the response body is known in
advance.
client.upgrade(options, callback?): Promise | void<Object><Function><Promise>
|
<void>callback
is not provided.See [dispatcher.upgrade(options[, callback])][]. Upgrades a connection to a
different protocol, such as for WebSocket or HTTP CONNECT.
<boolean>true after client.close() has been called.
<boolean>true after client.destroy() has been called, or after client.close() has
been called and the client shutdown has completed.
<number>The pipelining factor. This property can be read and written to adjust the number of concurrent requests sent over the connection. Only enable pipelining with trusted remote servers.
<ClientStats>Aggregate statistics for the client. See ClientStats.
<URL>Emitted when a socket has been created and connected. The client connects once
client.size > 0. See Dispatcher Event: 'connect'.
import { createServer } from 'node:http'
import { Client } from 'undici'
import { once } from 'node:events'
const server = createServer((request, response) => {
response.end('Hello, World!')
}).listen()
await once(server, 'listening')
const client = new Client(`http://localhost:${server.address().port}`)
client.on('connect', (origin) => {
console.log(`Connected to ${origin}`)
})
const { body } = await client.request({ path: '/', method: 'GET' })
body.setEncoding('utf8')
body.on('data', console.log)
client.close()
server.close()disconnect
History
The event is only emitted if the client had previously connected.
Emitted when a socket has disconnected. The error argument is the error that
caused the disconnection. The client reconnects if or once client.size > 0.
See Dispatcher Event: 'disconnect'.
import { createServer } from 'node:http'
import { Client } from 'undici'
import { once } from 'node:events'
const server = createServer((request, response) => {
response.destroy()
}).listen()
await once(server, 'listening')
const client = new Client(`http://localhost:${server.address().port}`)
client.on('disconnect', (origin) => {
console.log(`Disconnected from ${origin}`)
})
try {
await client.request({ path: '/', method: 'GET' })
} catch (error) {
console.error(error.message)
} finally {
client.close()
server.close()
}<URL>Emitted when the pipeline is no longer busy. See
Dispatcher Event: 'drain'.
import { createServer } from 'node:http'
import { Client } from 'undici'
import { once } from 'node:events'
const server = createServer((request, response) => {
response.end('Hello, World!')
}).listen()
await once(server, 'listening')
const client = new Client(`http://localhost:${server.address().port}`)
client.on('drain', () => {
console.log('drain event')
client.close()
server.close()
})
await Promise.all([
client.request({ path: '/', method: 'GET' }),
client.request({ path: '/', method: 'GET' }),
client.request({ path: '/', method: 'GET' })
])<Error>Emitted for user errors, such as throwing inside an onResponseError handler.
[dispatcher.close([callback])]: Dispatcher.md#dispatcherclosecallback
[dispatcher.connect()]: Dispatcher.md#dispatcherconnectoptions-callback
[dispatcher.destroy([error[, callback]])]: Dispatcher.md#dispatcherdestroyerror-callback
[dispatcher.dispatch(options, handler)]: Dispatcher.md#dispatcherdispatchoptions-handler
[dispatcher.pipeline(options, handler)]: Dispatcher.md#dispatcherpipelineoptions-handler
[dispatcher.request(options[, callback])]: Dispatcher.md#dispatcherrequestoptions-callback
[dispatcher.stream(options, factory[, callback])]: Dispatcher.md#dispatcherstreamoptions-factory-callback
[dispatcher.upgrade(options[, callback])]: Dispatcher.md#dispatcherupgradeoptions-callback
[tls.connect()]: https://nodejs.org/api/tls.html#tlsconnectoptions-callback