Socket
Socket
Sign inDemoInstall

undici

Package Overview
Dependencies
Maintainers
3
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 5.1.1 to 5.2.0

lib/global.js

1

docs/api/Errors.md

@@ -22,3 +22,2 @@ # Errors

| `InformationalError` | `UND_ERR_INFO` | expected error with reason |
| `TrailerMismatchError` | `UND_ERR_TRAILER_MISMATCH` | trailers did not match specification |

@@ -25,0 +24,0 @@ ### `SocketError`

'use strict'
const Agent = require('./lib/agent')
const { getGlobalDispatcher } = require('./lib/global')
const fetchImpl = require('./lib/fetch')
const globalDispatcher = new Agent()
const fetchImpl = require('./lib/fetch')
module.exports.fetch = async function fetch (resource) {
return fetchImpl.apply(globalDispatcher, arguments)
const dispatcher = (arguments[1] && arguments[1].dispatcher) || getGlobalDispatcher()
return fetchImpl.apply(dispatcher, arguments)
}

@@ -11,0 +10,0 @@ module.exports.FormData = require('./lib/fetch/formdata').FormData

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

const ProxyAgent = require('./lib/proxy-agent')
const { getGlobalDispatcher, setGlobalDispatcher } = require('./lib/global')

@@ -36,15 +37,2 @@ const nodeVersion = process.versions.node.split('.')

let globalDispatcher = new Agent()
function setGlobalDispatcher (agent) {
if (!agent || typeof agent.dispatch !== 'function') {
throw new InvalidArgumentError('Argument agent must implement Agent')
}
globalDispatcher = agent
}
function getGlobalDispatcher () {
return globalDispatcher
}
function makeDispatcher (fn) {

@@ -103,3 +91,3 @@ return (url, opts, handler) => {

}
const dispatcher = getGlobalDispatcher()
const dispatcher = (arguments[1] && arguments[1].dispatcher) || getGlobalDispatcher()
return fetchImpl.apply(dispatcher, arguments)

@@ -106,0 +94,0 @@ }

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

ResponseContentLengthMismatchError,
TrailerMismatchError,
InvalidArgumentError,

@@ -429,3 +428,2 @@ RequestAbortedError,

this.trailer = ''
this.keepAlive = ''

@@ -620,4 +618,2 @@ this.contentLength = ''

this.keepAlive += buf.toString()
} else if (key.length === 7 && key.toString().toLowerCase() === 'trailer') {
this.trailer += buf.toString()
} else if (key.length === 14 && key.toString().toLowerCase() === 'content-length') {

@@ -825,3 +821,3 @@ this.contentLength += buf.toString()

onMessageComplete () {
const { client, socket, statusCode, upgrade, trailer, headers, contentLength, bytesRead, shouldKeepAlive } = this
const { client, socket, statusCode, upgrade, headers, contentLength, bytesRead, shouldKeepAlive } = this

@@ -845,3 +841,2 @@ if (socket.destroyed && (!statusCode || shouldKeepAlive)) {

this.contentLength = ''
this.trailer = ''
this.keepAlive = ''

@@ -857,19 +852,2 @@

const trailers = trailer ? trailer.split(/,\s*/) : []
for (let i = 0; i < trailers.length; i++) {
const trailer = trailers[i]
let found = false
for (let n = 0; n < headers.length; n += 2) {
const key = headers[n]
if (key.length === trailer.length && key.toString().toLowerCase() === trailer.toLowerCase()) {
found = true
break
}
}
if (!found) {
util.destroy(socket, new TrailerMismatchError())
return -1
}
}
/* istanbul ignore next: should be handled by llhttp? */

@@ -876,0 +854,0 @@ if (request.method !== 'HEAD' && contentLength && bytesRead !== parseInt(contentLength, 10)) {

@@ -119,12 +119,2 @@ 'use strict'

class TrailerMismatchError extends UndiciError {
constructor (message) {
super(message)
Error.captureStackTrace(this, TrailerMismatchError)
this.name = 'TrailerMismatchError'
this.message = message || 'Trailers does not match trailer header'
this.code = 'UND_ERR_TRAILER_MISMATCH'
}
}
class ClientDestroyedError extends UndiciError {

@@ -200,3 +190,2 @@ constructor (message) {

ConnectTimeoutError,
TrailerMismatchError,
InvalidArgumentError,

@@ -203,0 +192,0 @@ InvalidReturnValueError,

@@ -80,2 +80,29 @@ // https://github.com/Ethan-Arrowood/undici-fetch

// https://tc39.es/ecma262/#sec-%25iteratorprototype%25-object
const esIteratorPrototype = Object.getPrototypeOf(Object.getPrototypeOf([][Symbol.iterator]()))
// https://webidl.spec.whatwg.org/#dfn-iterator-prototype-object
function makeHeadersIterator (iterator) {
const i = {
next () {
if (Object.getPrototypeOf(this) !== i) {
throw new TypeError(
'\'next\' called on an object that does not implement interface Headers Iterator.'
)
}
return iterator.next()
},
// The class string of an iterator prototype object for a given interface is the
// result of concatenating the identifier of the interface and the string " Iterator".
[Symbol.toStringTag]: 'Headers Iterator'
}
// The [[Prototype]] internal slot of an iterator prototype object must be %IteratorPrototype%.
Object.setPrototypeOf(i, esIteratorPrototype)
// esIteratorPrototype needs to be the prototype of i
// which is the prototype of an empty object. Yes, it's confusing.
return Object.setPrototypeOf({}, i)
}
class HeadersList {

@@ -173,10 +200,7 @@ constructor (init) {

get [Symbol.toStringTag] () {
if (!(this instanceof Headers)) {
throw new TypeError('Illegal invocation')
}
return this.constructor.name
}
toString () {
// https://fetch.spec.whatwg.org/#dom-headers-append
append (name, value) {
if (!(this instanceof Headers)) {

@@ -186,16 +210,9 @@ throw new TypeError('Illegal invocation')

return Object.prototype.toString.call(this)
}
append (...args) {
if (!(this instanceof Headers)) {
throw new TypeError('Illegal invocation')
}
if (args.length < 2) {
if (arguments.length < 2) {
throw new TypeError(
`Failed to execute 'append' on 'Headers': 2 arguments required, but only ${args.length} present.`
`Failed to execute 'append' on 'Headers': 2 arguments required, but only ${arguments.length} present.`
)
}
const normalizedName = normalizeAndValidateHeaderName(String(args[0]))
const normalizedName = normalizeAndValidateHeaderName(String(name))

@@ -218,16 +235,18 @@ if (this[kGuard] === 'immutable') {

return this[kHeadersList].append(String(args[0]), String(args[1]))
return this[kHeadersList].append(String(name), String(value))
}
delete (...args) {
// https://fetch.spec.whatwg.org/#dom-headers-delete
delete (name) {
if (!(this instanceof Headers)) {
throw new TypeError('Illegal invocation')
}
if (args.length < 1) {
if (arguments.length < 1) {
throw new TypeError(
`Failed to execute 'delete' on 'Headers': 1 argument required, but only ${args.length} present.`
`Failed to execute 'delete' on 'Headers': 1 argument required, but only ${arguments.length} present.`
)
}
const normalizedName = normalizeAndValidateHeaderName(String(args[0]))
const normalizedName = normalizeAndValidateHeaderName(String(name))

@@ -250,38 +269,44 @@ if (this[kGuard] === 'immutable') {

return this[kHeadersList].delete(String(args[0]))
return this[kHeadersList].delete(String(name))
}
get (...args) {
// https://fetch.spec.whatwg.org/#dom-headers-get
get (name) {
if (!(this instanceof Headers)) {
throw new TypeError('Illegal invocation')
}
if (args.length < 1) {
if (arguments.length < 1) {
throw new TypeError(
`Failed to execute 'get' on 'Headers': 1 argument required, but only ${args.length} present.`
`Failed to execute 'get' on 'Headers': 1 argument required, but only ${arguments.length} present.`
)
}
return this[kHeadersList].get(String(args[0]))
return this[kHeadersList].get(String(name))
}
has (...args) {
// https://fetch.spec.whatwg.org/#dom-headers-has
has (name) {
if (!(this instanceof Headers)) {
throw new TypeError('Illegal invocation')
}
if (args.length < 1) {
if (arguments.length < 1) {
throw new TypeError(
`Failed to execute 'has' on 'Headers': 1 argument required, but only ${args.length} present.`
`Failed to execute 'has' on 'Headers': 1 argument required, but only ${arguments.length} present.`
)
}
return this[kHeadersList].has(String(args[0]))
return this[kHeadersList].has(String(name))
}
set (...args) {
// https://fetch.spec.whatwg.org/#dom-headers-set
set (name, value) {
if (!(this instanceof Headers)) {
throw new TypeError('Illegal invocation')
}
if (args.length < 2) {
if (arguments.length < 2) {
throw new TypeError(
`Failed to execute 'set' on 'Headers': 2 arguments required, but only ${args.length} present.`
`Failed to execute 'set' on 'Headers': 2 arguments required, but only ${arguments.length} present.`
)

@@ -294,3 +319,3 @@ }

this[kGuard] === 'request' &&
forbiddenHeaderNames.includes(String(args[0]).toLocaleLowerCase())
forbiddenHeaderNames.includes(String(name).toLocaleLowerCase())
) {

@@ -302,3 +327,3 @@ return

this[kGuard] === 'response' &&
forbiddenResponseHeaderNames.includes(String(args[0]).toLocaleLowerCase())
forbiddenResponseHeaderNames.includes(String(name).toLocaleLowerCase())
) {

@@ -308,3 +333,3 @@ return

return this[kHeadersList].set(String(args[0]), String(args[1]))
return this[kHeadersList].set(String(name), String(value))
}

@@ -322,3 +347,3 @@

return this[kHeadersSortedMap].keys()
return makeHeadersIterator(this[kHeadersSortedMap].keys())
}

@@ -331,3 +356,3 @@

return this[kHeadersSortedMap].values()
return makeHeadersIterator(this[kHeadersSortedMap].values())
}

@@ -340,6 +365,10 @@

return this[kHeadersSortedMap].entries()
return makeHeadersIterator(this[kHeadersSortedMap].entries())
}
[Symbol.iterator] () {
/**
* @param {(value: string, key: string, self: Headers) => void} callbackFn
* @param {unknown} thisArg
*/
forEach (callbackFn, thisArg = globalThis) {
if (!(this instanceof Headers)) {

@@ -349,15 +378,9 @@ throw new TypeError('Illegal invocation')

return this[kHeadersSortedMap]
}
forEach (...args) {
if (!(this instanceof Headers)) {
throw new TypeError('Illegal invocation')
}
if (args.length < 1) {
if (arguments.length < 1) {
throw new TypeError(
`Failed to execute 'forEach' on 'Headers': 1 argument required, but only ${args.length} present.`
`Failed to execute 'forEach' on 'Headers': 1 argument required, but only ${arguments.length} present.`
)
}
if (typeof args[0] !== 'function') {
if (typeof callbackFn !== 'function') {
throw new TypeError(

@@ -367,8 +390,6 @@ "Failed to execute 'forEach' on 'Headers': parameter 1 is not of type 'Function'."

}
const callback = args[0]
const thisArg = args[1]
this[kHeadersSortedMap].forEach((value, index) => {
callback.apply(thisArg, [value, index, this])
})
for (const [key, value] of this) {
callbackFn.apply(thisArg, [value, key, this])
}
}

@@ -375,0 +396,0 @@

@@ -422,12 +422,6 @@ /* globals AbortController */

// list, append header’s name/header’s value to this’s headers.
if (headers instanceof Headers) {
// TODO (fix): Why doesn't this work?
// for (const [key, val] of headers[kHeadersList]) {
// this[kHeaders].append(key, val)
// }
this[kState].headersList = new HeadersList([
...this[kState].headersList,
...headers[kHeadersList]
])
if (headers.constructor.name === 'Headers') {
for (const [key, val] of headers[kHeadersList] || headers) {
this[kHeaders].append(key, val)
}
} else {

@@ -472,3 +466,2 @@ // 5. Otherwise, fill this’s headers with headers.

this[kHeaders].append('content-type', contentType)
this[kState].headersList.append('content-type', contentType)
}

@@ -475,0 +468,0 @@ }

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

case 511: return 'Network Authentication Required'
default:
throw new ReferenceError(`Unknown status code "${statusCode}"!`)
default: return 'unknown'
}

@@ -236,0 +235,0 @@ }

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

@@ -76,3 +76,3 @@ "homepage": "https://undici.nodejs.org",

"concurrently": "^7.1.0",
"cronometro": "^0.8.0",
"cronometro": "^1.0.5",
"delay": "^5.0.0",

@@ -83,5 +83,6 @@ "docsify-cli": "^4.4.3",

"husky": "^7.0.2",
"import-fresh": "^3.3.0",
"jest": "^28.0.1",
"jsfuzz": "^1.0.15",
"mocha": "^9.1.1",
"mocha": "^10.0.0",
"p-timeout": "^3.2.0",

@@ -92,3 +93,3 @@ "pre-commit": "^1.2.2",

"semver": "^7.3.5",
"sinon": "^13.0.2",
"sinon": "^14.0.0",
"snazzy": "^9.0.0",

@@ -95,0 +96,0 @@ "standard": "^17.0.0",

@@ -197,3 +197,18 @@ # undici

You can pass an optional dispatcher to `fetch` as:
```js
import { fetch, Agent } from 'undici'
const res = await fetch('https://example.com', {
// Mocks are also supported
dispatcher: new Agent({
keepAliveTimeout: 10,
keepAliveMaxTimeout: 10
})
})
const json = await res.json()
console.log(json)
```
#### `request.body`

@@ -200,0 +215,0 @@

@@ -10,2 +10,4 @@ // based on https://github.com/Ethan-Arrowood/undici-fetch/blob/249269714db874351589d2d364a0645d5160ae71/index.d.ts (MIT license)

import Dispatcher = require('./dispatcher')
export type RequestInfo = string | URL | Request

@@ -40,5 +42,17 @@

export interface HeadersIterator<T, TReturn = any, TNext = undefined> {
next(...args: [] | [TNext]): IteratorResult<T, TReturn>;
}
export interface HeadersIterableIterator<T> extends HeadersIterator<T> {
[Symbol.iterator](): HeadersIterableIterator<T>;
}
export interface HeadersIterable<T> {
[Symbol.iterator](): HeadersIterator<T>;
}
export type HeadersInit = string[][] | Record<string, string | ReadonlyArray<string>> | Headers
export declare class Headers implements Iterable<[string, string]> {
export declare class Headers implements HeadersIterable<[string, string]> {
constructor (init?: HeadersInit)

@@ -55,6 +69,6 @@ readonly append: (name: string, value: string) => void

readonly keys: () => IterableIterator<string>
readonly values: () => IterableIterator<string>
readonly entries: () => IterableIterator<[string, string]>
readonly [Symbol.iterator]: () => Iterator<[string, string]>
readonly keys: () => HeadersIterableIterator<string>
readonly values: () => HeadersIterableIterator<string>
readonly entries: () => HeadersIterableIterator<[string, string]>
readonly [Symbol.iterator]: () => HeadersIterator<[string, string]>
}

@@ -105,2 +119,3 @@

readonly window?: null
readonly dispatcher?: Dispatcher
}

@@ -107,0 +122,0 @@

Sorry, the diff of this file is too big to display

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