Comparing version 3.0.0 to 3.1.0
import Pool from './types/pool' | ||
import Client from './types/client' | ||
import Errors from './types/errors' | ||
import errors from './types/errors' | ||
export { Pool, Client, Errors } | ||
export { Pool, Client, errors } | ||
export default Undici | ||
@@ -7,0 +7,0 @@ |
@@ -77,4 +77,6 @@ 'use strict' | ||
socketTimeout, | ||
requestTimeout, | ||
bodyTimeout, | ||
idleTimeout, | ||
keepAlive, | ||
keepAliveTimeout, | ||
@@ -90,6 +92,14 @@ maxKeepAliveTimeout, | ||
if (keepAlive !== undefined) { | ||
throw new InvalidArgumentError('unsupported keepAlive, use pipelining=0 instead') | ||
} | ||
if (socketTimeout !== undefined) { | ||
throw new InvalidArgumentError('unsupported socketTimeout') | ||
throw new InvalidArgumentError('unsupported socketTimeout, use headersTimeout & bodyTimeout instead') | ||
} | ||
if (requestTimeout !== undefined) { | ||
throw new InvalidArgumentError('unsupported requestTimeout, use headersTimeout & bodyTimeout instead') | ||
} | ||
if (idleTimeout !== undefined) { | ||
@@ -423,3 +433,3 @@ throw new InvalidArgumentError('unsupported idleTimeout, use keepAliveTimeout instead') | ||
socketResume(socket) | ||
socketResume(this.socket) | ||
} | ||
@@ -434,3 +444,3 @@ | ||
socketPause(socket) | ||
socketPause(this.socket) | ||
} | ||
@@ -706,3 +716,7 @@ } | ||
request.onComplete(headers) | ||
try { | ||
request.onComplete(headers) | ||
} catch (err) { | ||
request.onError(err) | ||
} | ||
} catch (err) { | ||
@@ -1071,3 +1085,3 @@ util.destroy(socket, err) | ||
if (write(client, request)) { | ||
if (!request.aborted && write(client, request)) { | ||
const parser = client[kSocket][kParser] | ||
@@ -1074,0 +1088,0 @@ if (!parser.timeout && client[kHeadersTimeout]) { |
'use strict' | ||
const EventEmitter = require('events') | ||
const Client = require('./core/client') | ||
@@ -17,3 +18,3 @@ const { | ||
class Pool { | ||
class Pool extends EventEmitter { | ||
constructor (url, { | ||
@@ -23,2 +24,4 @@ connections, | ||
} = {}) { | ||
super() | ||
if (connections != null && (!Number.isFinite(connections) || connections <= 0)) { | ||
@@ -55,4 +58,14 @@ throw new InvalidArgumentError('invalid connections') | ||
function onConnect () { | ||
pool.emit('connect', this) | ||
} | ||
function onDisconnect () { | ||
pool.emit('disconnect', this) | ||
} | ||
for (const client of this[kClients]) { | ||
client.on('drain', onDrain) | ||
client.on('connect', onConnect) | ||
client.on('disconnect', onDisconnect) | ||
} | ||
@@ -59,0 +72,0 @@ } |
{ | ||
"name": "undici", | ||
"version": "3.0.0", | ||
"version": "3.1.0", | ||
"description": "An HTTP/1.1 client, written from scratch for Node.js", | ||
@@ -10,3 +10,3 @@ "main": "index.js", | ||
"lint": "standard | snazzy", | ||
"test": "tap test/*.{mjs,js} --no-coverage && jest test/jest/test", | ||
"test": "tap test/*.js --no-coverage && jest test/jest/test", | ||
"test:typescript": "tsd", | ||
@@ -13,0 +13,0 @@ "coverage": "standard | snazzy && tap test/*.js", |
@@ -41,7 +41,7 @@ # undici | ||
A basic HTTP/1.1 client, mapped on top a single TCP/TLS connection. Pipelining is disabled | ||
A basic HTTP/1.1 client, mapped on top of a single TCP/TLS connection. Pipelining is disabled | ||
by default. | ||
`url` can be a string or a [`URL`](https://nodejs.org/api/url.html#url_class_url) object. | ||
It should only include the protocol, hostname, and the port. | ||
It should only include the protocol, hostname, and port. | ||
@@ -68,7 +68,7 @@ Options: | ||
- `headersTimeout: Number`, the timeout after which a request will time out, in | ||
milliseconds. Monitors time between receiving a complete headers. | ||
milliseconds. Monitors time between receiving complete headers. | ||
Use `0` to disable it entirely. Default: `30e3` milliseconds (30s). | ||
- `bodyTimeout: Number`, the timeout after which a request will time out, in | ||
milliseconds. Monitors time between receiving a body data. | ||
milliseconds. Monitors time between receiving body data. | ||
Use `0` to disable it entirely. Default: `30e3` milliseconds (30s). | ||
@@ -585,2 +585,10 @@ | ||
#### Events | ||
* `'connect'`, emitted when a client has connected, the `Client` | ||
instance is passed as argument. | ||
* `'disconnect'`, emitted when a client has disconnected, the `Client` | ||
instance is passed as argument. | ||
<a name='errors'></a> | ||
@@ -587,0 +595,0 @@ ### `undici.errors` |
@@ -364,3 +364,3 @@ 'use strict' | ||
try { | ||
const client = new Client(new URL('http://localhost:200')) | ||
const client = new Client(new URL('http://localhost:200')) // eslint-disable-line | ||
client.destroy(null, null) | ||
@@ -374,4 +374,4 @@ t.fail() | ||
try { | ||
const client = new Client(new URL('http://localhost:200')) | ||
client.close(null) | ||
const client = new Client(new URL('http://localhost:200')) // eslint-disable-line | ||
client.close(null, null) | ||
t.fail() | ||
@@ -384,4 +384,3 @@ } catch (err) { | ||
try { | ||
const client = new Client(new URL('http://localhost:200'), { maxKeepAliveTimeout: 1e3 }) | ||
client.close(null) | ||
new Client(new URL('http://localhost:200'), { maxKeepAliveTimeout: 1e3 }) // eslint-disable-line | ||
t.fail() | ||
@@ -394,20 +393,23 @@ } catch (err) { | ||
try { | ||
new Client(new URL('http://localhost:200'), { idleTimeout: 30e3 }) // eslint-disable-line | ||
new Client(new URL('http://localhost:200'), { keepAlive: false }) // eslint-disable-line | ||
t.fail() | ||
} catch (err) { | ||
t.ok(err instanceof errors.InvalidArgumentError) | ||
t.strictEqual(err.message, 'unsupported idleTimeout, use keepAliveTimeout instead') | ||
t.strictEqual(err.message, 'unsupported keepAlive, use pipelining=0 instead') | ||
} | ||
try { | ||
new Client(new URL('http://localhost:200'), { socketTimeout: 30e3 }) // eslint-disable-line | ||
new Client(new URL('http://localhost:200'), { idleTimeout: 30e3 }) // eslint-disable-line | ||
t.fail() | ||
} catch (err) { | ||
t.ok(err instanceof errors.InvalidArgumentError) | ||
t.strictEqual(err.message, 'unsupported socketTimeout') | ||
t.strictEqual(err.message, 'unsupported idleTimeout, use keepAliveTimeout instead') | ||
} | ||
try { | ||
new Client(new URL('http://localhost:200'), { headersTimeout: 30e3 }) // eslint-disable-line | ||
new Client(new URL('http://localhost:200'), { socketTimeout: 30e3 }) // eslint-disable-line | ||
t.fail() | ||
} catch (err) { | ||
t.ok(err instanceof errors.InvalidArgumentError) | ||
t.strictEqual(err.message, 'unsupported headersTimeout') | ||
t.strictEqual(err.message, 'unsupported socketTimeout, use headersTimeout & bodyTimeout instead') | ||
} | ||
@@ -414,0 +416,0 @@ |
@@ -255,3 +255,3 @@ 'use strict' | ||
const client = new Client(`http://localhost:${server.address().port}`, { | ||
keepAlive: false | ||
pipelining: 0 | ||
}) | ||
@@ -258,0 +258,0 @@ t.teardown(client.destroy.bind(client)) |
@@ -6,3 +6,3 @@ 'use strict' | ||
const undici = require('..') | ||
const { Pool, errors } = require('..') | ||
const { Client, Pool, errors } = require('..') | ||
const { createServer } = require('http') | ||
@@ -16,2 +16,42 @@ const { EventEmitter } = require('events') | ||
test('connect/disconnect event(s)', (t) => { | ||
const clients = 2 | ||
t.plan(clients * 3) | ||
const server = createServer((req, res) => { | ||
res.writeHead(200, { | ||
Connection: 'keep-alive', | ||
'Keep-Alive': 'timeout=1s' | ||
}) | ||
res.end('ok') | ||
}) | ||
t.tearDown(server.close.bind(server)) | ||
server.listen(0, () => { | ||
const pool = new Pool(`http://localhost:${server.address().port}`, { | ||
connections: clients, | ||
keepAliveTimeoutThreshold: 100 | ||
}) | ||
t.tearDown(pool.close.bind(pool)) | ||
pool.on('connect', (client) => { | ||
t.strictEqual(client instanceof Client, true) | ||
}) | ||
pool.on('disconnect', (client) => { | ||
t.strictEqual(client instanceof Client, true) | ||
}) | ||
for (let i = 0; i < clients; i++) { | ||
pool.request({ | ||
path: '/', | ||
method: 'GET' | ||
}, (err, { headers, body }) => { | ||
t.error(err) | ||
body.resume() | ||
}) | ||
} | ||
}) | ||
}) | ||
test('basic get', (t) => { | ||
@@ -56,3 +96,43 @@ t.plan(9) | ||
}) | ||
test('URL as arg', (t) => { | ||
t.plan(9) | ||
const server = createServer((req, res) => { | ||
t.strictEqual('/', req.url) | ||
t.strictEqual('GET', req.method) | ||
res.setHeader('content-type', 'text/plain') | ||
res.end('hello') | ||
}) | ||
t.tearDown(server.close.bind(server)) | ||
server.listen(0, async () => { | ||
const url = new URL('http://localhost') | ||
url.port = server.address().port | ||
const client = undici(url) | ||
t.tearDown(client.destroy.bind(client)) | ||
client.request({ path: '/', method: 'GET' }, (err, { statusCode, headers, body }) => { | ||
t.error(err) | ||
t.strictEqual(statusCode, 200) | ||
t.strictEqual(headers['content-type'], 'text/plain') | ||
const bufs = [] | ||
body.on('data', (buf) => { | ||
bufs.push(buf) | ||
}) | ||
body.on('end', () => { | ||
t.strictEqual('hello', Buffer.concat(bufs).toString('utf8')) | ||
}) | ||
}) | ||
client.close((err) => { | ||
t.error(err) | ||
client.destroy((err) => { | ||
t.error(err) | ||
client.close((err) => { | ||
t.ok(err instanceof errors.ClientDestroyedError) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) | ||
test('basic get error async/await', (t) => { | ||
@@ -59,0 +139,0 @@ t.plan(2) |
import { Duplex, Readable, Writable } from 'stream' | ||
import { expectAssignable } from 'tsd' | ||
import { Client } from '../..' | ||
import { URL } from 'url' | ||
expectAssignable<Client>(new Client('')) | ||
expectAssignable<Client>(new Client('', {})) | ||
expectAssignable<Client>(new Client(new URL('http://localhost'), {})) | ||
@@ -8,0 +10,0 @@ { |
import { expectAssignable } from 'tsd' | ||
import { Errors } from '../..' | ||
import { errors } from '../..' | ||
expectAssignable<Errors.UndiciError>(new Errors.UndiciError()) | ||
expectAssignable<errors.UndiciError>(new errors.UndiciError()) | ||
expectAssignable<Errors.UndiciError>(new Errors.HeadersTimeoutError()) | ||
expectAssignable<Errors.HeadersTimeoutError>(new Errors.HeadersTimeoutError()) | ||
expectAssignable<'HeadersTimeoutError'>(new Errors.HeadersTimeoutError().name) | ||
expectAssignable<'UND_ERR_HEADERS_TIMEOUT'>(new Errors.HeadersTimeoutError().code) | ||
expectAssignable<errors.UndiciError>(new errors.HeadersTimeoutError()) | ||
expectAssignable<errors.HeadersTimeoutError>(new errors.HeadersTimeoutError()) | ||
expectAssignable<'HeadersTimeoutError'>(new errors.HeadersTimeoutError().name) | ||
expectAssignable<'UND_ERR_HEADERS_TIMEOUT'>(new errors.HeadersTimeoutError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.SocketTimeoutError()) | ||
expectAssignable<Errors.SocketTimeoutError>(new Errors.SocketTimeoutError()) | ||
expectAssignable<'SocketTimeoutError'>(new Errors.SocketTimeoutError().name) | ||
expectAssignable<'UND_ERR_SOCKET_TIMEOUT'>(new Errors.SocketTimeoutError().code) | ||
expectAssignable<errors.UndiciError>(new errors.SocketTimeoutError()) | ||
expectAssignable<errors.SocketTimeoutError>(new errors.SocketTimeoutError()) | ||
expectAssignable<'SocketTimeoutError'>(new errors.SocketTimeoutError().name) | ||
expectAssignable<'UND_ERR_SOCKET_TIMEOUT'>(new errors.SocketTimeoutError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.InvalidReturnError()) | ||
expectAssignable<Errors.InvalidReturnError>(new Errors.InvalidReturnError()) | ||
expectAssignable<'InvalidReturnError'>(new Errors.InvalidReturnError().name) | ||
expectAssignable<'UND_ERR_INVALID_RETURN_VALUE'>(new Errors.InvalidReturnError().code) | ||
expectAssignable<errors.UndiciError>(new errors.InvalidReturnError()) | ||
expectAssignable<errors.InvalidReturnError>(new errors.InvalidReturnError()) | ||
expectAssignable<'InvalidReturnError'>(new errors.InvalidReturnError().name) | ||
expectAssignable<'UND_ERR_INVALID_RETURN_VALUE'>(new errors.InvalidReturnError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.RequestAbortedError()) | ||
expectAssignable<Errors.RequestAbortedError>(new Errors.RequestAbortedError()) | ||
expectAssignable<'RequestAbortedError'>(new Errors.RequestAbortedError().name) | ||
expectAssignable<'UND_ERR_ABORTED'>(new Errors.RequestAbortedError().code) | ||
expectAssignable<errors.UndiciError>(new errors.RequestAbortedError()) | ||
expectAssignable<errors.RequestAbortedError>(new errors.RequestAbortedError()) | ||
expectAssignable<'RequestAbortedError'>(new errors.RequestAbortedError().name) | ||
expectAssignable<'UND_ERR_ABORTED'>(new errors.RequestAbortedError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.InformationalError()) | ||
expectAssignable<Errors.InformationalError>(new Errors.InformationalError()) | ||
expectAssignable<'InformationalError'>(new Errors.InformationalError().name) | ||
expectAssignable<'UND_ERR_INFO'>(new Errors.InformationalError().code) | ||
expectAssignable<errors.UndiciError>(new errors.InformationalError()) | ||
expectAssignable<errors.InformationalError>(new errors.InformationalError()) | ||
expectAssignable<'InformationalError'>(new errors.InformationalError().name) | ||
expectAssignable<'UND_ERR_INFO'>(new errors.InformationalError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.ContentLengthMismatchError()) | ||
expectAssignable<Errors.ContentLengthMismatchError>(new Errors.ContentLengthMismatchError()) | ||
expectAssignable<'ContentLengthMismatchError'>(new Errors.ContentLengthMismatchError().name) | ||
expectAssignable<'UND_ERR_CONTENT_LENGTH_MISMATCH'>(new Errors.ContentLengthMismatchError().code) | ||
expectAssignable<errors.UndiciError>(new errors.ContentLengthMismatchError()) | ||
expectAssignable<errors.ContentLengthMismatchError>(new errors.ContentLengthMismatchError()) | ||
expectAssignable<'ContentLengthMismatchError'>(new errors.ContentLengthMismatchError().name) | ||
expectAssignable<'UND_ERR_CONTENT_LENGTH_MISMATCH'>(new errors.ContentLengthMismatchError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.ClientDestroyedError()) | ||
expectAssignable<Errors.ClientDestroyedError>(new Errors.ClientDestroyedError()) | ||
expectAssignable<'ClientDestroyedError'>(new Errors.ClientDestroyedError().name) | ||
expectAssignable<'UND_ERR_DESTROYED'>(new Errors.ClientDestroyedError().code) | ||
expectAssignable<errors.UndiciError>(new errors.ClientDestroyedError()) | ||
expectAssignable<errors.ClientDestroyedError>(new errors.ClientDestroyedError()) | ||
expectAssignable<'ClientDestroyedError'>(new errors.ClientDestroyedError().name) | ||
expectAssignable<'UND_ERR_DESTROYED'>(new errors.ClientDestroyedError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.ClientClosedError()) | ||
expectAssignable<Errors.ClientClosedError>(new Errors.ClientClosedError()) | ||
expectAssignable<'ClientClosedError'>(new Errors.ClientClosedError().name) | ||
expectAssignable<'UND_ERR_CLOSED'>(new Errors.ClientClosedError().code) | ||
expectAssignable<errors.UndiciError>(new errors.ClientClosedError()) | ||
expectAssignable<errors.ClientClosedError>(new errors.ClientClosedError()) | ||
expectAssignable<'ClientClosedError'>(new errors.ClientClosedError().name) | ||
expectAssignable<'UND_ERR_CLOSED'>(new errors.ClientClosedError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.SocketError()) | ||
expectAssignable<Errors.SocketError>(new Errors.SocketError()) | ||
expectAssignable<'SocketError'>(new Errors.SocketError().name) | ||
expectAssignable<'UND_ERR_SOCKET'>(new Errors.SocketError().code) | ||
expectAssignable<errors.UndiciError>(new errors.SocketError()) | ||
expectAssignable<errors.SocketError>(new errors.SocketError()) | ||
expectAssignable<'SocketError'>(new errors.SocketError().name) | ||
expectAssignable<'UND_ERR_SOCKET'>(new errors.SocketError().code) | ||
expectAssignable<Errors.UndiciError>(new Errors.NotSupportedError()) | ||
expectAssignable<Errors.NotSupportedError>(new Errors.NotSupportedError()) | ||
expectAssignable<'NotSupportedError'>(new Errors.NotSupportedError().name) | ||
expectAssignable<'UND_ERR_NOT_SUPPORTED'>(new Errors.NotSupportedError().code) | ||
expectAssignable<errors.UndiciError>(new errors.NotSupportedError()) | ||
expectAssignable<errors.NotSupportedError>(new errors.NotSupportedError()) | ||
expectAssignable<'NotSupportedError'>(new errors.NotSupportedError().name) | ||
expectAssignable<'UND_ERR_NOT_SUPPORTED'>(new errors.NotSupportedError().code) | ||
{ | ||
// @ts-ignore | ||
function f (): Errors.HeadersTimeoutError | Errors.SocketTimeoutError { return } | ||
function f (): errors.HeadersTimeoutError | errors.SocketTimeoutError { return } | ||
@@ -63,6 +63,6 @@ const e = f() | ||
if (e.code === 'UND_ERR_HEADERS_TIMEOUT') { | ||
expectAssignable<Errors.HeadersTimeoutError>(e) | ||
expectAssignable<errors.HeadersTimeoutError>(e) | ||
} else if (e.code === 'UND_ERR_SOCKET_TIMEOUT') { | ||
expectAssignable<Errors.SocketTimeoutError>(e) | ||
expectAssignable<errors.SocketTimeoutError>(e) | ||
} | ||
} |
import { expectAssignable } from 'tsd' | ||
import Undici, { Pool, Client, Errors } from '../..' | ||
import Undici, { Pool, Client, errors } from '../..' | ||
@@ -7,2 +7,2 @@ expectAssignable<Pool>(Undici('', {})) | ||
expectAssignable<Client>(new Undici.Client('', {})) | ||
expectAssignable<typeof Errors>(Undici.errors) | ||
expectAssignable<typeof errors>(Undici.errors) |
import { Duplex, Readable, Writable } from 'stream' | ||
import { expectAssignable } from 'tsd' | ||
import { Client, Pool } from '../..' | ||
import { URL } from 'url' | ||
expectAssignable<Pool>(new Pool('')) | ||
expectAssignable<Pool>(new Pool('', {})) | ||
expectAssignable<Pool>(new Pool(new URL('http://localhost'), {})) | ||
@@ -8,0 +10,0 @@ { |
import Client from './client' | ||
import { URL } from 'url' | ||
@@ -6,3 +7,3 @@ export = Pool | ||
declare class Pool extends Client { | ||
constructor(url: string, options?: Pool.Options) | ||
constructor(url: string | URL, options?: Pool.Options) | ||
} | ||
@@ -9,0 +10,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
399216
12874
659