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 4.0.0-alpha.3 to 4.0.0-alpha.4

41

index.js

@@ -38,7 +38,32 @@ 'use strict'

function makeDispatcher (fn) {
return (url, { agent, dispatcher = getGlobalDispatcher(), method = 'GET', ...opts } = {}, ...additionalArgs) => {
if (opts.path != null) {
throw new InvalidArgumentError('unsupported opts.path')
return (url, opts, handler) => {
if (typeof opts === 'function') {
handler = opts
opts = null
}
if (!url || (typeof url !== 'string' && typeof url !== 'object' && !(url instanceof URL))) {
throw new InvalidArgumentError('invalid url')
}
if (opts != null && typeof opts !== 'object') {
throw new InvalidArgumentError('invalid opts')
}
if (opts && opts.path != null) {
if (typeof opts.path !== 'string') {
throw new InvalidArgumentError('invalid opts.path')
}
url = new URL(opts.path, util.parseOrigin(url))
} else {
if (!opts) {
opts = typeof url === 'object' ? url : {}
}
url = util.parseURL(url)
}
const { agent, dispatcher = getGlobalDispatcher() } = opts
if (agent) {

@@ -48,6 +73,8 @@ throw new InvalidArgumentError('unsupported opts.agent. Did you mean opts.client?')

const { origin, pathname, search } = util.parseURL(url)
const path = search ? `${pathname}${search}` : pathname
return fn.call(dispatcher, { ...opts, origin, method, path }, ...additionalArgs)
return fn.call(dispatcher, {
...opts,
origin: url.origin,
path: url.search ? `${url.pathname}${url.search}` : url.pathname,
method: opts.method ? opts.method : opts.body ? 'PUT' : 'GET'
}, handler)
}

@@ -54,0 +81,0 @@ }

2

lib/agent.js

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

this[kClients] = new Map()
this[kFinalizer] = new FinalizationRegistry(key => /* istanbul ignore next: gc is undeterministic */{
this[kFinalizer] = new FinalizationRegistry(/* istanbul ignore next: gc is undeterministic */ key => {
const ref = this[kClients].get(key)

@@ -52,0 +52,0 @@ if (ref !== undefined && ref.deref() === undefined) {

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

class HTTPParserError extends Error {
constructor (message, code) {
constructor (message, code, data) {
super(message)

@@ -395,2 +395,3 @@ Error.captureStackTrace(this, HTTPParserError)

this.code = code ? `HPE_${code}` : undefined
this.data = data.toString()
}

@@ -404,12 +405,4 @@ }

wasm_on_message_begin: p => {
return 0
},
wasm_on_url: /* istanbul ignore next: not used */ (p, at, length) => {
return 0
},
wasm_on_status: (p, at, length) => {
return 0
},
wasm_on_header_field: (p, at, len) => {
assert.strictEqual(currentParser.ptr, p)
const start = at - currentParser.bufferPtr

@@ -420,2 +413,3 @@ const end = start + len

wasm_on_header_value: (p, at, len) => {
assert.strictEqual(currentParser.ptr, p)
const start = at - currentParser.bufferPtr

@@ -425,9 +419,8 @@ const end = start + len

},
wasm_on_headers_complete: p => {
const statusCode = llhttp.exports.llhttp_get_status_code(p)
const upgrade = Boolean(llhttp.exports.llhttp_get_upgrade(p))
const shouldKeepAlive = Boolean(llhttp.exports.llhttp_should_keep_alive(p))
return currentParser.onHeadersComplete(statusCode, upgrade, shouldKeepAlive) || 0
wasm_on_headers_complete: (p, statusCode, upgrade, shouldKeepAlive) => {
assert.strictEqual(currentParser.ptr, p)
return currentParser.onHeadersComplete(statusCode, Boolean(upgrade), Boolean(shouldKeepAlive)) || 0
},
wasm_on_body: (p, at, len) => {
assert.strictEqual(currentParser.ptr, p)
const start = at - currentParser.bufferPtr

@@ -438,2 +431,3 @@ const end = start + len

wasm_on_message_complete: (p) => {
assert.strictEqual(currentParser.ptr, p)
return currentParser.onMessageComplete() || 0

@@ -456,4 +450,4 @@ }

this.ptr = llhttp.exports.llhttp_alloc(constants.TYPE.RESPONSE)
this.bufferSize = 0
this.bufferPtr = null
this.bufferSize = 16384
this.bufferPtr = llhttp.exports.malloc(this.bufferSize)
this.bufferRef = null

@@ -472,7 +466,3 @@ this.client = client

this.paused = false
this.resume = this.resume.bind(this)
this.execute = this.execute.bind(this)
socket.on('data', this.execute)
}

@@ -514,6 +504,3 @@

this.socket.resume()
if (!this.socket.readableLength) {
this.execute(EMPTY_BUF) // Flush parser.
}
this.execute(EMPTY_BUF) // Flush parser.
}

@@ -524,2 +511,3 @@

assert(currentParser == null)
assert(!this.paused)

@@ -530,5 +518,3 @@ const { socket } = this

if (data.length > this.bufferSize) {
if (this.bufferPtr) {
llhttp.exports.free(this.bufferPtr)
}
llhttp.exports.free(this.bufferPtr)
this.bufferSize = Math.ceil(data.length / 4096) * 4096

@@ -538,9 +524,6 @@ this.bufferPtr = llhttp.exports.malloc(this.bufferSize)

if (data.length) {
assert(this.bufferPtr != null)
assert(this.bufferSize >= data.length)
assert(this.bufferSize >= data.length)
// TODO (perf): Can we avoid this copy somehow?
new Uint8Array(llhttp.exports.memory.buffer, this.bufferPtr, this.bufferSize).set(data)
}
// TODO (perf): Can we avoid this copy somehow?
new Uint8Array(llhttp.exports.memory.buffer, this.bufferPtr, this.bufferSize).set(data)

@@ -557,28 +540,40 @@ // Call `execute` on the wasm parser.

if (ret === constants.ERROR.OK) {
return
}
const offset = llhttp.exports.llhttp_get_error_pos(this.ptr) - this.bufferPtr
if (ret === constants.ERROR.PAUSED_UPGRADE) {
const offset = llhttp.exports.llhttp_get_error_pos(this.ptr) - this.bufferPtr
this.onUpgrade(data.slice(offset))
} else if (ret === constants.ERROR.PAUSED) {
const offset = llhttp.exports.llhttp_get_error_pos(this.ptr) - this.bufferPtr
this.paused = true
socket.pause()
socket.unshift(data.slice(offset))
} else {
} else if (ret !== constants.ERROR.OK) {
const ptr = llhttp.exports.llhttp_get_error_reason(this.ptr)
let message
let message = ''
if (ptr) {
const len = new Uint8Array(llhttp.exports.memory.buffer).indexOf(0, ptr) - ptr
const len = new Uint8Array(llhttp.exports.memory.buffer, ptr).indexOf(0)
message = Buffer.from(llhttp.exports.memory.buffer, ptr, len).toString()
} else {
message = ''
}
const code = constants.ERROR[ret]
util.destroy(socket, new HTTPParserError(message, code))
util.destroy(socket, new HTTPParserError(message, constants.ERROR[ret], data))
}
}
destroy () {
assert(this.ptr != null)
assert(this.bufferPtr != null)
assert(currentParser == null)
llhttp.exports.llhttp_free(this.ptr)
this.ptr = null
llhttp.exports.free(this.bufferPtr)
this.bufferPtr = null
clearTimeout(this.timeout)
this.timeout = null
this.timeoutValue = null
this.timeoutType = null
this.paused = false
}
onHeaderField (buf) {

@@ -732,9 +727,9 @@ const len = this.headers.length

if (!keepAlive && key.length === 10 && key.toString().toLowerCase() === 'keep-alive') {
keepAlive = val.toString()
keepAlive = val
} else if (!trailers && key.length === 7 && key.toString().toLowerCase() === 'trailer') {
trailers = val.toString()
trailers = val
}
}
this.trailers = trailers ? trailers.toLowerCase().split(/,\s*/) : []
this.trailers = trailers ? trailers.toString().toLowerCase().split(/,\s*/) : []

@@ -878,24 +873,2 @@ if (shouldKeepAlive && client[kPipelining]) {

}
destroy () {
assert(this.ptr != null)
assert(currentParser == null)
llhttp.exports.llhttp_free(this.ptr)
this.ptr = null
if (this.bufferPtr != null) {
llhttp.exports.free(this.bufferPtr)
this.bufferPtr = null
}
clearTimeout(this.timeout)
this.timeout = null
this.timeoutValue = null
this.timeoutType = null
this.paused = false
this.socket.removeListener('data', this.execute)
}
}

@@ -906,2 +879,3 @@

/* istanbul ignore else */
if (timeoutType === TIMEOUT_HEADERS) {

@@ -913,16 +887,19 @@ if (!socket[kWriting]) {

} else if (timeoutType === TIMEOUT_BODY) {
if (!socket.isPaused()) {
if (!parser.paused) {
util.destroy(socket, new BodyTimeoutError())
}
} else if (timeoutType === TIMEOUT_IDLE) {
if (client[kRunning] === 0 && client[kKeepAliveTimeoutValue]) {
util.destroy(socket, new InformationalError('socket idle timeout'))
}
assert(client[kRunning] === 0 && client[kKeepAliveTimeoutValue])
util.destroy(socket, new InformationalError('socket idle timeout'))
} else if (timeoutType === TIMEOUT_CONNECT) {
if (!client[kConnected]) {
util.destroy(socket, new ConnectTimeoutError())
}
assert(!client[kConnected])
util.destroy(socket, new ConnectTimeoutError())
}
}
function onSocketData (data) {
const { [kParser]: parser } = this
parser.execute(data)
}
function onSocketConnect () {

@@ -976,2 +953,3 @@ const { [kClient]: client } = this

.removeListener('error', onSocketError)
.removeListener('data', onSocketData)
.removeListener('end', onSocketEnd)

@@ -1073,2 +1051,3 @@ .removeListener('close', onSocketClose)

.on('error', onSocketError)
.on('data', onSocketData)
.on('end', onSocketEnd)

@@ -1075,0 +1054,0 @@ .on('close', onSocketClose)

@@ -38,2 +38,10 @@ 'use strict'

if (url.path != null && typeof url.path !== 'string') {
throw new InvalidArgumentError('invalid path')
}
if (url.pathname != null && typeof url.pathname !== 'string') {
throw new InvalidArgumentError('invalid pathname')
}
if (url.hostname != null && typeof url.hostname !== 'string') {

@@ -43,3 +51,7 @@ throw new InvalidArgumentError('invalid hostname')

if (!/https?/.test(url.protocol)) {
if (url.origin != null && typeof url.origin !== 'string') {
throw new InvalidArgumentError('invalid origin')
}
if (!/^https?:/.test(url.origin || url.protocol)) {
throw new InvalidArgumentError('invalid protocol')

@@ -49,9 +61,13 @@ }

if (!(url instanceof URL)) {
const port = url.port || {
'http:': 80,
'https:': 443
}[url.protocol]
assert(port != null)
const path = url.path || `${url.pathname || '/'}${url.search || ''}`
url = new URL(`${url.protocol}//${url.hostname}:${port}${path}`)
const port = url.port != null
? url.port
: { 'http:': 80, 'https:': 443 }[url.protocol]
const origin = url.origin != null
? url.origin
: `${url.protocol}//${url.hostname}:${port}`
const path = url.path != null
? url.path
: `${url.pathname || ''}${url.search || ''}`
url = new URL(path, origin)
}

@@ -134,3 +150,3 @@

function parseKeepAliveTimeout (val) {
const m = val.match(KEEPALIVE_TIMEOUT_EXPR)
const m = val.toString().match(KEEPALIVE_TIMEOUT_EXPR)
return m ? parseInt(m[1]) * 1000 : null

@@ -137,0 +153,0 @@ }

{
"name": "undici",
"version": "4.0.0-alpha.3",
"version": "4.0.0-alpha.4",
"description": "An HTTP/1.1 client, written from scratch for Node.js",

@@ -46,7 +46,7 @@ "homepage": "https://undici.nodejs.org",

"devDependencies": {
"@sinonjs/fake-timers": "^6.0.1",
"@types/node": "^14.6.2",
"@sinonjs/fake-timers": "^7.0.5",
"@types/node": "^14.14.39",
"abort-controller": "^3.0.0",
"benchmark": "^2.1.4",
"concurrently": "^6.0.0",
"concurrently": "^6.0.2",
"docsify-cli": "^4.4.2",

@@ -53,0 +53,0 @@ "https-pem": "^2.0.0",

@@ -60,3 +60,3 @@ # undici

### `undici.request(url[, options]): Promise`
### `undici.request([url, options]): Promise`

@@ -68,3 +68,3 @@ Arguments:

* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcherdispatcher)
* **method** `String` - Default: `GET`
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
* **maxRedirections** `Integer` - Default: `0`

@@ -80,3 +80,3 @@

### `undici.stream(url, options, factory): Promise`
### `undici.stream([url, options, ]factory): Promise`

@@ -88,3 +88,3 @@ Arguments:

* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcherdispatcher)
* **method** `String` - Default: `GET`
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
* **factory** `Dispatcher.stream.factory`

@@ -94,4 +94,2 @@

`url` may contain pathname. `options` may not contain path.
Calls `options.dispatcher.stream(options, factory)`.

@@ -101,3 +99,3 @@

### `undici.pipeline(url, options, handler): Duplex`
### `undici.pipeline([url, options, ]handler): Duplex`

@@ -109,3 +107,3 @@ Arguments:

* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcherdispatcher)
* **method** `String` - Default: `GET`
* **method** `String` - Default: `PUT` if `options.body`, otherwise `GET`
* **handler** `Dispatcher.pipeline.handler`

@@ -115,4 +113,2 @@

`url` may contain pathname. `options` may not contain path.
Calls `options.dispatch.pipeline(options, handler)`.

@@ -122,3 +118,3 @@

### `undici.connect(options[, callback])`
### `undici.connect([url, options]): Promise`

@@ -129,5 +125,5 @@ Starts two-way communications with the requested resource using [HTTP CONNECT](https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/CONNECT).

* **url** `string | URL | object`
* **options** [`ConnectOptions`](docs/api/Dispatcher.md#parameter-connectoptions)
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcherdispatcher)
* **method** `String` - Default: `GET`
* **callback** `(err: Error | null, data: ConnectData | null) => void` (optional)

@@ -137,4 +133,2 @@

`url` may contain pathname. `options` may not contain path.
Calls `options.dispatch.connect(options)`.

@@ -144,3 +138,3 @@

### `undici.upgrade(options[, callback])`
### `undici.upgrade([url, options]): Promise`

@@ -151,5 +145,5 @@ Upgrade to a different protocol. See [MDN - HTTP - Protocol upgrade mechanism](https://developer.mozilla.org/en-US/docs/Web/HTTP/Protocol_upgrade_mechanism) for more details.

* **url** `string | URL | object`
* **options** [`UpgradeOptions`](docs/api/Dispatcher.md#parameter-upgradeoptions)
* **dispatcher** `Dispatcher` - Default: [getGlobalDispatcher](#undicigetglobaldispatcherdispatcher)
* **method** `String` - Default: `GET`
* **callback** `(error: Error | null, data: UpgradeData) => void` (optional)

@@ -159,4 +153,2 @@

`url` may contain pathname. `options` may not contain path.
Calls `options.dispatcher.upgrade(options)`.

@@ -215,7 +207,13 @@

* [__Daniele Belardi__](https://github.com/dnlup), <https://www.npmjs.com/~dnlup>
* [__Tomas Della Vedova__](https://github.com/delvedor), <https://www.npmjs.com/~delvedor>
* [__Matteo Collina__](https://github.com/mcollina), <https://www.npmjs.com/~matteo.collina>
* [__Robert Nagy__](https://github.com/ronag), <https://www.npmjs.com/~ronag>
### Releasers
* [__Matteo Collina__](https://github.com/mcollina), <https://www.npmjs.com/~matteo.collina>
* [__Robert Nagy__](https://github.com/ronag), <https://www.npmjs.com/~ronag>
## License
MIT

Sorry, the diff of this file is not supported yet

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