diff options
Diffstat (limited to 'includes/external/addressbook/node_modules/http2-wrapper/source')
22 files changed, 0 insertions, 2238 deletions
diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/agent.js b/includes/external/addressbook/node_modules/http2-wrapper/source/agent.js deleted file mode 100644 index 922d202..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/agent.js +++ /dev/null @@ -1,796 +0,0 @@ -'use strict'; -// See https://github.com/facebook/jest/issues/2549 -// eslint-disable-next-line node/prefer-global/url -const {URL} = require('url'); -const EventEmitter = require('events'); -const tls = require('tls'); -const http2 = require('http2'); -const QuickLRU = require('quick-lru'); -const delayAsyncDestroy = require('./utils/delay-async-destroy.js'); - -const kCurrentStreamCount = Symbol('currentStreamCount'); -const kRequest = Symbol('request'); -const kOriginSet = Symbol('cachedOriginSet'); -const kGracefullyClosing = Symbol('gracefullyClosing'); -const kLength = Symbol('length'); - -const nameKeys = [ - // Not an Agent option actually - 'createConnection', - - // `http2.connect()` options - 'maxDeflateDynamicTableSize', - 'maxSettings', - 'maxSessionMemory', - 'maxHeaderListPairs', - 'maxOutstandingPings', - 'maxReservedRemoteStreams', - 'maxSendHeaderBlockLength', - 'paddingStrategy', - 'peerMaxConcurrentStreams', - 'settings', - - // `tls.connect()` source options - 'family', - 'localAddress', - 'rejectUnauthorized', - - // `tls.connect()` secure context options - 'pskCallback', - 'minDHSize', - - // `tls.connect()` destination options - // - `servername` is automatically validated, skip it - // - `host` and `port` just describe the destination server, - 'path', - 'socket', - - // `tls.createSecureContext()` options - 'ca', - 'cert', - 'sigalgs', - 'ciphers', - 'clientCertEngine', - 'crl', - 'dhparam', - 'ecdhCurve', - 'honorCipherOrder', - 'key', - 'privateKeyEngine', - 'privateKeyIdentifier', - 'maxVersion', - 'minVersion', - 'pfx', - 'secureOptions', - 'secureProtocol', - 'sessionIdContext', - 'ticketKeys' -]; - -const getSortedIndex = (array, value, compare) => { - let low = 0; - let high = array.length; - - while (low < high) { - const mid = (low + high) >>> 1; - - if (compare(array[mid], value)) { - low = mid + 1; - } else { - high = mid; - } - } - - return low; -}; - -const compareSessions = (a, b) => a.remoteSettings.maxConcurrentStreams > b.remoteSettings.maxConcurrentStreams; - -// See https://tools.ietf.org/html/rfc8336 -const closeCoveredSessions = (where, session) => { - // Clients SHOULD NOT emit new requests on any connection whose Origin - // Set is a proper subset of another connection's Origin Set, and they - // SHOULD close it once all outstanding requests are satisfied. - for (let index = 0; index < where.length; index++) { - const coveredSession = where[index]; - - if ( - // Unfortunately `.every()` returns true for an empty array - coveredSession[kOriginSet].length > 0 - - // The set is a proper subset when its length is less than the other set. - && coveredSession[kOriginSet].length < session[kOriginSet].length - - // And the other set includes all elements of the subset. - && coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) - - // Makes sure that the session can handle all requests from the covered session. - && (coveredSession[kCurrentStreamCount] + session[kCurrentStreamCount]) <= session.remoteSettings.maxConcurrentStreams - ) { - // This allows pending requests to finish and prevents making new requests. - gracefullyClose(coveredSession); - } - } -}; - -// This is basically inverted `closeCoveredSessions(...)`. -const closeSessionIfCovered = (where, coveredSession) => { - for (let index = 0; index < where.length; index++) { - const session = where[index]; - - if ( - coveredSession[kOriginSet].length > 0 - && coveredSession[kOriginSet].length < session[kOriginSet].length - && coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) - && (coveredSession[kCurrentStreamCount] + session[kCurrentStreamCount]) <= session.remoteSettings.maxConcurrentStreams - ) { - gracefullyClose(coveredSession); - - return true; - } - } - - return false; -}; - -const gracefullyClose = session => { - session[kGracefullyClosing] = true; - - if (session[kCurrentStreamCount] === 0) { - session.close(); - } -}; - -class Agent extends EventEmitter { - constructor({timeout = 0, maxSessions = Number.POSITIVE_INFINITY, maxEmptySessions = 10, maxCachedTlsSessions = 100} = {}) { - super(); - - // SESSIONS[NORMALIZED_OPTIONS] = []; - this.sessions = {}; - - // The queue for creating new sessions. It looks like this: - // QUEUE[NORMALIZED_OPTIONS][NORMALIZED_ORIGIN] = ENTRY_FUNCTION - // - // It's faster when there are many origins. If there's only one, then QUEUE[`${options}:${origin}`] is faster. - // I guess object creation / deletion is causing the slowdown. - // - // The entry function has `listeners`, `completed` and `destroyed` properties. - // `listeners` is an array of objects containing `resolve` and `reject` functions. - // `completed` is a boolean. It's set to true after ENTRY_FUNCTION is executed. - // `destroyed` is a boolean. If it's set to true, the session will be destroyed if hasn't connected yet. - this.queue = {}; - - // Each session will use this timeout value. - this.timeout = timeout; - - // Max sessions in total - this.maxSessions = maxSessions; - - // Max empty sessions in total - this.maxEmptySessions = maxEmptySessions; - - this._emptySessionCount = 0; - this._sessionCount = 0; - - // We don't support push streams by default. - this.settings = { - enablePush: false, - initialWindowSize: 1024 * 1024 * 32 // 32MB, see https://github.com/nodejs/node/issues/38426 - }; - - // Reusing TLS sessions increases performance. - this.tlsSessionCache = new QuickLRU({maxSize: maxCachedTlsSessions}); - } - - get protocol() { - return 'https:'; - } - - normalizeOptions(options) { - let normalized = ''; - - for (let index = 0; index < nameKeys.length; index++) { - const key = nameKeys[index]; - - normalized += ':'; - - if (options && options[key] !== undefined) { - normalized += options[key]; - } - } - - return normalized; - } - - _processQueue() { - if (this._sessionCount >= this.maxSessions) { - this.closeEmptySessions(this.maxSessions - this._sessionCount + 1); - return; - } - - // eslint-disable-next-line guard-for-in - for (const normalizedOptions in this.queue) { - // eslint-disable-next-line guard-for-in - for (const normalizedOrigin in this.queue[normalizedOptions]) { - const item = this.queue[normalizedOptions][normalizedOrigin]; - - // The entry function can be run only once. - if (!item.completed) { - item.completed = true; - - item(); - } - } - } - } - - _isBetterSession(thisStreamCount, thatStreamCount) { - return thisStreamCount > thatStreamCount; - } - - _accept(session, listeners, normalizedOrigin, options) { - let index = 0; - - while (index < listeners.length && session[kCurrentStreamCount] < session.remoteSettings.maxConcurrentStreams) { - // We assume `resolve(...)` calls `request(...)` *directly*, - // otherwise the session will get overloaded. - listeners[index].resolve(session); - - index++; - } - - listeners.splice(0, index); - - if (listeners.length > 0) { - this.getSession(normalizedOrigin, options, listeners); - listeners.length = 0; - } - } - - getSession(origin, options, listeners) { - return new Promise((resolve, reject) => { - if (Array.isArray(listeners) && listeners.length > 0) { - listeners = [...listeners]; - - // Resolve the current promise ASAP, we're just moving the listeners. - // They will be executed at a different time. - resolve(); - } else { - listeners = [{resolve, reject}]; - } - - try { - // Parse origin - if (typeof origin === 'string') { - origin = new URL(origin); - } else if (!(origin instanceof URL)) { - throw new TypeError('The `origin` argument needs to be a string or an URL object'); - } - - if (options) { - // Validate servername - const {servername} = options; - const {hostname} = origin; - if (servername && hostname !== servername) { - throw new Error(`Origin ${hostname} differs from servername ${servername}`); - } - } - } catch (error) { - for (let index = 0; index < listeners.length; index++) { - listeners[index].reject(error); - } - - return; - } - - const normalizedOptions = this.normalizeOptions(options); - const normalizedOrigin = origin.origin; - - if (normalizedOptions in this.sessions) { - const sessions = this.sessions[normalizedOptions]; - - let maxConcurrentStreams = -1; - let currentStreamsCount = -1; - let optimalSession; - - // We could just do this.sessions[normalizedOptions].find(...) but that isn't optimal. - // Additionally, we are looking for session which has biggest current pending streams count. - // - // |------------| |------------| |------------| |------------| - // | Session: A | | Session: B | | Session: C | | Session: D | - // | Pending: 5 |-| Pending: 8 |-| Pending: 9 |-| Pending: 4 | - // | Max: 10 | | Max: 10 | | Max: 9 | | Max: 5 | - // |------------| |------------| |------------| |------------| - // ^ - // | - // pick this one -- - // - for (let index = 0; index < sessions.length; index++) { - const session = sessions[index]; - - const sessionMaxConcurrentStreams = session.remoteSettings.maxConcurrentStreams; - - if (sessionMaxConcurrentStreams < maxConcurrentStreams) { - break; - } - - if (!session[kOriginSet].includes(normalizedOrigin)) { - continue; - } - - const sessionCurrentStreamsCount = session[kCurrentStreamCount]; - - if ( - sessionCurrentStreamsCount >= sessionMaxConcurrentStreams - || session[kGracefullyClosing] - // Unfortunately the `close` event isn't called immediately, - // so `session.destroyed` is `true`, but `session.closed` is `false`. - || session.destroyed - ) { - continue; - } - - // We only need set this once. - if (!optimalSession) { - maxConcurrentStreams = sessionMaxConcurrentStreams; - } - - // Either get the session which has biggest current stream count or the lowest. - if (this._isBetterSession(sessionCurrentStreamsCount, currentStreamsCount)) { - optimalSession = session; - currentStreamsCount = sessionCurrentStreamsCount; - } - } - - if (optimalSession) { - this._accept(optimalSession, listeners, normalizedOrigin, options); - return; - } - } - - if (normalizedOptions in this.queue) { - if (normalizedOrigin in this.queue[normalizedOptions]) { - // There's already an item in the queue, just attach ourselves to it. - this.queue[normalizedOptions][normalizedOrigin].listeners.push(...listeners); - return; - } - } else { - this.queue[normalizedOptions] = { - [kLength]: 0 - }; - } - - // The entry must be removed from the queue IMMEDIATELY when: - // 1. the session connects successfully, - // 2. an error occurs. - const removeFromQueue = () => { - // Our entry can be replaced. We cannot remove the new one. - if (normalizedOptions in this.queue && this.queue[normalizedOptions][normalizedOrigin] === entry) { - delete this.queue[normalizedOptions][normalizedOrigin]; - - if (--this.queue[normalizedOptions][kLength] === 0) { - delete this.queue[normalizedOptions]; - } - } - }; - - // The main logic is here - const entry = async () => { - this._sessionCount++; - - const name = `${normalizedOrigin}:${normalizedOptions}`; - let receivedSettings = false; - let socket; - - try { - const computedOptions = {...options}; - - if (computedOptions.settings === undefined) { - computedOptions.settings = this.settings; - } - - if (computedOptions.session === undefined) { - computedOptions.session = this.tlsSessionCache.get(name); - } - - const createConnection = computedOptions.createConnection || this.createConnection; - - // A hacky workaround to enable async `createConnection` - socket = await createConnection.call(this, origin, computedOptions); - computedOptions.createConnection = () => socket; - - const session = http2.connect(origin, computedOptions); - session[kCurrentStreamCount] = 0; - session[kGracefullyClosing] = false; - - // Node.js return https://false:443 instead of https://1.1.1.1:443 - const getOriginSet = () => { - const {socket} = session; - - let originSet; - if (socket.servername === false) { - socket.servername = socket.remoteAddress; - originSet = session.originSet; - socket.servername = false; - } else { - originSet = session.originSet; - } - - return originSet; - }; - - const isFree = () => session[kCurrentStreamCount] < session.remoteSettings.maxConcurrentStreams; - - session.socket.once('session', tlsSession => { - this.tlsSessionCache.set(name, tlsSession); - }); - - session.once('error', error => { - // Listeners are empty when the session successfully connected. - for (let index = 0; index < listeners.length; index++) { - listeners[index].reject(error); - } - - // The connection got broken, purge the cache. - this.tlsSessionCache.delete(name); - }); - - session.setTimeout(this.timeout, () => { - // Terminates all streams owned by this session. - session.destroy(); - }); - - session.once('close', () => { - this._sessionCount--; - - if (receivedSettings) { - // Assumes session `close` is emitted after request `close` - this._emptySessionCount--; - - // This cannot be moved to the stream logic, - // because there may be a session that hadn't made a single request. - const where = this.sessions[normalizedOptions]; - - if (where.length === 1) { - delete this.sessions[normalizedOptions]; - } else { - where.splice(where.indexOf(session), 1); - } - } else { - // Broken connection - removeFromQueue(); - - const error = new Error('Session closed without receiving a SETTINGS frame'); - error.code = 'HTTP2WRAPPER_NOSETTINGS'; - - for (let index = 0; index < listeners.length; index++) { - listeners[index].reject(error); - } - } - - // There may be another session awaiting. - this._processQueue(); - }); - - // Iterates over the queue and processes listeners. - const processListeners = () => { - const queue = this.queue[normalizedOptions]; - if (!queue) { - return; - } - - const originSet = session[kOriginSet]; - - for (let index = 0; index < originSet.length; index++) { - const origin = originSet[index]; - - if (origin in queue) { - const {listeners, completed} = queue[origin]; - - let index = 0; - - // Prevents session overloading. - while (index < listeners.length && isFree()) { - // We assume `resolve(...)` calls `request(...)` *directly*, - // otherwise the session will get overloaded. - listeners[index].resolve(session); - - index++; - } - - queue[origin].listeners.splice(0, index); - - if (queue[origin].listeners.length === 0 && !completed) { - delete queue[origin]; - - if (--queue[kLength] === 0) { - delete this.queue[normalizedOptions]; - break; - } - } - - // We're no longer free, no point in continuing. - if (!isFree()) { - break; - } - } - } - }; - - // The Origin Set cannot shrink. No need to check if it suddenly became covered by another one. - session.on('origin', () => { - session[kOriginSet] = getOriginSet() || []; - session[kGracefullyClosing] = false; - closeSessionIfCovered(this.sessions[normalizedOptions], session); - - if (session[kGracefullyClosing] || !isFree()) { - return; - } - - processListeners(); - - if (!isFree()) { - return; - } - - // Close covered sessions (if possible). - closeCoveredSessions(this.sessions[normalizedOptions], session); - }); - - session.once('remoteSettings', () => { - // The Agent could have been destroyed already. - if (entry.destroyed) { - const error = new Error('Agent has been destroyed'); - - for (let index = 0; index < listeners.length; index++) { - listeners[index].reject(error); - } - - session.destroy(); - return; - } - - // See https://github.com/nodejs/node/issues/38426 - if (session.setLocalWindowSize) { - session.setLocalWindowSize(1024 * 1024 * 4); // 4 MB - } - - session[kOriginSet] = getOriginSet() || []; - - if (session.socket.encrypted) { - const mainOrigin = session[kOriginSet][0]; - if (mainOrigin !== normalizedOrigin) { - const error = new Error(`Requested origin ${normalizedOrigin} does not match server ${mainOrigin}`); - - for (let index = 0; index < listeners.length; index++) { - listeners[index].reject(error); - } - - session.destroy(); - return; - } - } - - removeFromQueue(); - - { - const where = this.sessions; - - if (normalizedOptions in where) { - const sessions = where[normalizedOptions]; - sessions.splice(getSortedIndex(sessions, session, compareSessions), 0, session); - } else { - where[normalizedOptions] = [session]; - } - } - - receivedSettings = true; - this._emptySessionCount++; - - this.emit('session', session); - this._accept(session, listeners, normalizedOrigin, options); - - if (session[kCurrentStreamCount] === 0 && this._emptySessionCount > this.maxEmptySessions) { - this.closeEmptySessions(this._emptySessionCount - this.maxEmptySessions); - } - - // `session.remoteSettings.maxConcurrentStreams` might get increased - session.on('remoteSettings', () => { - if (!isFree()) { - return; - } - - processListeners(); - - if (!isFree()) { - return; - } - - // In case the Origin Set changes - closeCoveredSessions(this.sessions[normalizedOptions], session); - }); - }); - - // Shim `session.request()` in order to catch all streams - session[kRequest] = session.request; - session.request = (headers, streamOptions) => { - if (session[kGracefullyClosing]) { - throw new Error('The session is gracefully closing. No new streams are allowed.'); - } - - const stream = session[kRequest](headers, streamOptions); - - // The process won't exit until the session is closed or all requests are gone. - session.ref(); - - if (session[kCurrentStreamCount]++ === 0) { - this._emptySessionCount--; - } - - stream.once('close', () => { - if (--session[kCurrentStreamCount] === 0) { - this._emptySessionCount++; - session.unref(); - - if (this._emptySessionCount > this.maxEmptySessions || session[kGracefullyClosing]) { - session.close(); - return; - } - } - - if (session.destroyed || session.closed) { - return; - } - - if (isFree() && !closeSessionIfCovered(this.sessions[normalizedOptions], session)) { - closeCoveredSessions(this.sessions[normalizedOptions], session); - processListeners(); - - if (session[kCurrentStreamCount] === 0) { - this._processQueue(); - } - } - }); - - return stream; - }; - } catch (error) { - removeFromQueue(); - this._sessionCount--; - - for (let index = 0; index < listeners.length; index++) { - listeners[index].reject(error); - } - } - }; - - entry.listeners = listeners; - entry.completed = false; - entry.destroyed = false; - - this.queue[normalizedOptions][normalizedOrigin] = entry; - this.queue[normalizedOptions][kLength]++; - this._processQueue(); - }); - } - - request(origin, options, headers, streamOptions) { - return new Promise((resolve, reject) => { - this.getSession(origin, options, [{ - reject, - resolve: session => { - try { - const stream = session.request(headers, streamOptions); - - // Do not throw before `request(...)` has been awaited - delayAsyncDestroy(stream); - - resolve(stream); - } catch (error) { - reject(error); - } - } - }]); - }); - } - - async createConnection(origin, options) { - return Agent.connect(origin, options); - } - - static connect(origin, options) { - options.ALPNProtocols = ['h2']; - - const port = origin.port || 443; - const host = origin.hostname; - - if (typeof options.servername === 'undefined') { - options.servername = host; - } - - const socket = tls.connect(port, host, options); - - if (options.socket) { - socket._peername = { - family: undefined, - address: undefined, - port - }; - } - - return socket; - } - - closeEmptySessions(maxCount = Number.POSITIVE_INFINITY) { - let closedCount = 0; - - const {sessions} = this; - - // eslint-disable-next-line guard-for-in - for (const key in sessions) { - const thisSessions = sessions[key]; - - for (let index = 0; index < thisSessions.length; index++) { - const session = thisSessions[index]; - - if (session[kCurrentStreamCount] === 0) { - closedCount++; - session.close(); - - if (closedCount >= maxCount) { - return closedCount; - } - } - } - } - - return closedCount; - } - - destroy(reason) { - const {sessions, queue} = this; - - // eslint-disable-next-line guard-for-in - for (const key in sessions) { - const thisSessions = sessions[key]; - - for (let index = 0; index < thisSessions.length; index++) { - thisSessions[index].destroy(reason); - } - } - - // eslint-disable-next-line guard-for-in - for (const normalizedOptions in queue) { - const entries = queue[normalizedOptions]; - - // eslint-disable-next-line guard-for-in - for (const normalizedOrigin in entries) { - entries[normalizedOrigin].destroyed = true; - } - } - - // New requests should NOT attach to destroyed sessions - this.queue = {}; - this.tlsSessionCache.clear(); - } - - get emptySessionCount() { - return this._emptySessionCount; - } - - get pendingSessionCount() { - return this._sessionCount - this._emptySessionCount; - } - - get sessionCount() { - return this._sessionCount; - } -} - -Agent.kCurrentStreamCount = kCurrentStreamCount; -Agent.kGracefullyClosing = kGracefullyClosing; - -module.exports = { - Agent, - globalAgent: new Agent() -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/auto.js b/includes/external/addressbook/node_modules/http2-wrapper/source/auto.js deleted file mode 100644 index 6085d0d..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/auto.js +++ /dev/null @@ -1,206 +0,0 @@ -'use strict'; -// See https://github.com/facebook/jest/issues/2549 -// eslint-disable-next-line node/prefer-global/url -const {URL, urlToHttpOptions} = require('url'); -const http = require('http'); -const https = require('https'); -const resolveALPN = require('resolve-alpn'); -const QuickLRU = require('quick-lru'); -const {Agent, globalAgent} = require('./agent.js'); -const Http2ClientRequest = require('./client-request.js'); -const calculateServerName = require('./utils/calculate-server-name.js'); -const delayAsyncDestroy = require('./utils/delay-async-destroy.js'); - -const cache = new QuickLRU({maxSize: 100}); -const queue = new Map(); - -const installSocket = (agent, socket, options) => { - socket._httpMessage = {shouldKeepAlive: true}; - - const onFree = () => { - agent.emit('free', socket, options); - }; - - socket.on('free', onFree); - - const onClose = () => { - agent.removeSocket(socket, options); - }; - - socket.on('close', onClose); - - const onTimeout = () => { - const {freeSockets} = agent; - - for (const sockets of Object.values(freeSockets)) { - if (sockets.includes(socket)) { - socket.destroy(); - return; - } - } - }; - - socket.on('timeout', onTimeout); - - const onRemove = () => { - agent.removeSocket(socket, options); - socket.off('close', onClose); - socket.off('free', onFree); - socket.off('timeout', onTimeout); - socket.off('agentRemove', onRemove); - }; - - socket.on('agentRemove', onRemove); - - agent.emit('free', socket, options); -}; - -const createResolveProtocol = (cache, queue = new Map(), connect = undefined) => { - return async options => { - const name = `${options.host}:${options.port}:${options.ALPNProtocols.sort()}`; - - if (!cache.has(name)) { - if (queue.has(name)) { - const result = await queue.get(name); - return {alpnProtocol: result.alpnProtocol}; - } - - const {path} = options; - options.path = options.socketPath; - - const resultPromise = resolveALPN(options, connect); - queue.set(name, resultPromise); - - try { - const result = await resultPromise; - - cache.set(name, result.alpnProtocol); - queue.delete(name); - - options.path = path; - - return result; - } catch (error) { - queue.delete(name); - - options.path = path; - - throw error; - } - } - - return {alpnProtocol: cache.get(name)}; - }; -}; - -const defaultResolveProtocol = createResolveProtocol(cache, queue); - -module.exports = async (input, options, callback) => { - if (typeof input === 'string') { - input = urlToHttpOptions(new URL(input)); - } else if (input instanceof URL) { - input = urlToHttpOptions(input); - } else { - input = {...input}; - } - - if (typeof options === 'function' || options === undefined) { - // (options, callback) - callback = options; - options = input; - } else { - // (input, options, callback) - options = Object.assign(input, options); - } - - options.ALPNProtocols = options.ALPNProtocols || ['h2', 'http/1.1']; - - if (!Array.isArray(options.ALPNProtocols) || options.ALPNProtocols.length === 0) { - throw new Error('The `ALPNProtocols` option must be an Array with at least one entry'); - } - - options.protocol = options.protocol || 'https:'; - const isHttps = options.protocol === 'https:'; - - options.host = options.hostname || options.host || 'localhost'; - options.session = options.tlsSession; - options.servername = options.servername || calculateServerName((options.headers && options.headers.host) || options.host); - options.port = options.port || (isHttps ? 443 : 80); - options._defaultAgent = isHttps ? https.globalAgent : http.globalAgent; - - const resolveProtocol = options.resolveProtocol || defaultResolveProtocol; - - // Note: We don't support `h2session` here - - let {agent} = options; - if (agent !== undefined && agent !== false && agent.constructor.name !== 'Object') { - throw new Error('The `options.agent` can be only an object `http`, `https` or `http2` properties'); - } - - if (isHttps) { - options.resolveSocket = true; - - let {socket, alpnProtocol, timeout} = await resolveProtocol(options); - - if (timeout) { - if (socket) { - socket.destroy(); - } - - const error = new Error(`Timed out resolving ALPN: ${options.timeout} ms`); - error.code = 'ETIMEDOUT'; - error.ms = options.timeout; - - throw error; - } - - // We can't accept custom `createConnection` because the API is different for HTTP/2 - if (socket && options.createConnection) { - socket.destroy(); - socket = undefined; - } - - delete options.resolveSocket; - - const isHttp2 = alpnProtocol === 'h2'; - - if (agent) { - agent = isHttp2 ? agent.http2 : agent.https; - options.agent = agent; - } - - if (agent === undefined) { - agent = isHttp2 ? globalAgent : https.globalAgent; - } - - if (socket) { - if (agent === false) { - socket.destroy(); - } else { - const defaultCreateConnection = (isHttp2 ? Agent : https.Agent).prototype.createConnection; - - if (agent.createConnection === defaultCreateConnection) { - if (isHttp2) { - options._reuseSocket = socket; - } else { - installSocket(agent, socket, options); - } - } else { - socket.destroy(); - } - } - } - - if (isHttp2) { - return delayAsyncDestroy(new Http2ClientRequest(options, callback)); - } - } else if (agent) { - options.agent = agent.http; - } - - return delayAsyncDestroy(http.request(options, callback)); -}; - -module.exports.protocolCache = cache; -module.exports.resolveProtocol = defaultResolveProtocol; -module.exports.createResolveProtocol = createResolveProtocol; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/client-request.js b/includes/external/addressbook/node_modules/http2-wrapper/source/client-request.js deleted file mode 100644 index 2fd2266..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/client-request.js +++ /dev/null @@ -1,563 +0,0 @@ -'use strict'; -// See https://github.com/facebook/jest/issues/2549 -// eslint-disable-next-line node/prefer-global/url -const {URL, urlToHttpOptions} = require('url'); -const http2 = require('http2'); -const {Writable} = require('stream'); -const {Agent, globalAgent} = require('./agent.js'); -const IncomingMessage = require('./incoming-message.js'); -const proxyEvents = require('./utils/proxy-events.js'); -const { - ERR_INVALID_ARG_TYPE, - ERR_INVALID_PROTOCOL, - ERR_HTTP_HEADERS_SENT -} = require('./utils/errors.js'); -const validateHeaderName = require('./utils/validate-header-name.js'); -const validateHeaderValue = require('./utils/validate-header-value.js'); -const proxySocketHandler = require('./utils/proxy-socket-handler.js'); - -const { - HTTP2_HEADER_STATUS, - HTTP2_HEADER_METHOD, - HTTP2_HEADER_PATH, - HTTP2_HEADER_AUTHORITY, - HTTP2_METHOD_CONNECT -} = http2.constants; - -const kHeaders = Symbol('headers'); -const kOrigin = Symbol('origin'); -const kSession = Symbol('session'); -const kOptions = Symbol('options'); -const kFlushedHeaders = Symbol('flushedHeaders'); -const kJobs = Symbol('jobs'); -const kPendingAgentPromise = Symbol('pendingAgentPromise'); - -class ClientRequest extends Writable { - constructor(input, options, callback) { - super({ - autoDestroy: false, - emitClose: false - }); - - if (typeof input === 'string') { - input = urlToHttpOptions(new URL(input)); - } else if (input instanceof URL) { - input = urlToHttpOptions(input); - } else { - input = {...input}; - } - - if (typeof options === 'function' || options === undefined) { - // (options, callback) - callback = options; - options = input; - } else { - // (input, options, callback) - options = Object.assign(input, options); - } - - if (options.h2session) { - this[kSession] = options.h2session; - - if (this[kSession].destroyed) { - throw new Error('The session has been closed already'); - } - - this.protocol = this[kSession].socket.encrypted ? 'https:' : 'http:'; - } else if (options.agent === false) { - this.agent = new Agent({maxEmptySessions: 0}); - } else if (typeof options.agent === 'undefined' || options.agent === null) { - this.agent = globalAgent; - } else if (typeof options.agent.request === 'function') { - this.agent = options.agent; - } else { - throw new ERR_INVALID_ARG_TYPE('options.agent', ['http2wrapper.Agent-like Object', 'undefined', 'false'], options.agent); - } - - if (this.agent) { - this.protocol = this.agent.protocol; - } - - if (options.protocol && options.protocol !== this.protocol) { - throw new ERR_INVALID_PROTOCOL(options.protocol, this.protocol); - } - - if (!options.port) { - options.port = options.defaultPort || (this.agent && this.agent.defaultPort) || 443; - } - - options.host = options.hostname || options.host || 'localhost'; - - // Unused - delete options.hostname; - - const {timeout} = options; - options.timeout = undefined; - - this[kHeaders] = Object.create(null); - this[kJobs] = []; - - this[kPendingAgentPromise] = undefined; - - this.socket = null; - this.connection = null; - - this.method = options.method || 'GET'; - - if (!(this.method === 'CONNECT' && (options.path === '/' || options.path === undefined))) { - this.path = options.path; - } - - this.res = null; - this.aborted = false; - this.reusedSocket = false; - - const {headers} = options; - if (headers) { - // eslint-disable-next-line guard-for-in - for (const header in headers) { - this.setHeader(header, headers[header]); - } - } - - if (options.auth && !('authorization' in this[kHeaders])) { - this[kHeaders].authorization = 'Basic ' + Buffer.from(options.auth).toString('base64'); - } - - options.session = options.tlsSession; - options.path = options.socketPath; - - this[kOptions] = options; - - // Clients that generate HTTP/2 requests directly SHOULD use the :authority pseudo-header field instead of the Host header field. - this[kOrigin] = new URL(`${this.protocol}//${options.servername || options.host}:${options.port}`); - - // A socket is being reused - const reuseSocket = options._reuseSocket; - if (reuseSocket) { - options.createConnection = (...args) => { - if (reuseSocket.destroyed) { - return this.agent.createConnection(...args); - } - - return reuseSocket; - }; - - // eslint-disable-next-line promise/prefer-await-to-then - this.agent.getSession(this[kOrigin], this[kOptions]).catch(() => {}); - } - - if (timeout) { - this.setTimeout(timeout); - } - - if (callback) { - this.once('response', callback); - } - - this[kFlushedHeaders] = false; - } - - get method() { - return this[kHeaders][HTTP2_HEADER_METHOD]; - } - - set method(value) { - if (value) { - this[kHeaders][HTTP2_HEADER_METHOD] = value.toUpperCase(); - } - } - - get path() { - const header = this.method === 'CONNECT' ? HTTP2_HEADER_AUTHORITY : HTTP2_HEADER_PATH; - - return this[kHeaders][header]; - } - - set path(value) { - if (value) { - const header = this.method === 'CONNECT' ? HTTP2_HEADER_AUTHORITY : HTTP2_HEADER_PATH; - - this[kHeaders][header] = value; - } - } - - get host() { - return this[kOrigin].hostname; - } - - set host(_value) { - // Do nothing as this is read only. - } - - get _mustNotHaveABody() { - return this.method === 'GET' || this.method === 'HEAD' || this.method === 'DELETE'; - } - - _write(chunk, encoding, callback) { - // https://github.com/nodejs/node/blob/654df09ae0c5e17d1b52a900a545f0664d8c7627/lib/internal/http2/util.js#L148-L156 - if (this._mustNotHaveABody) { - callback(new Error('The GET, HEAD and DELETE methods must NOT have a body')); - /* istanbul ignore next: Node.js 12 throws directly */ - return; - } - - this.flushHeaders(); - - const callWrite = () => this._request.write(chunk, encoding, callback); - if (this._request) { - callWrite(); - } else { - this[kJobs].push(callWrite); - } - } - - _final(callback) { - this.flushHeaders(); - - const callEnd = () => { - // For GET, HEAD and DELETE and CONNECT - if (this._mustNotHaveABody || this.method === 'CONNECT') { - callback(); - return; - } - - this._request.end(callback); - }; - - if (this._request) { - callEnd(); - } else { - this[kJobs].push(callEnd); - } - } - - abort() { - if (this.res && this.res.complete) { - return; - } - - if (!this.aborted) { - process.nextTick(() => this.emit('abort')); - } - - this.aborted = true; - - this.destroy(); - } - - async _destroy(error, callback) { - if (this.res) { - this.res._dump(); - } - - if (this._request) { - this._request.destroy(); - } else { - process.nextTick(() => { - this.emit('close'); - }); - } - - try { - await this[kPendingAgentPromise]; - } catch (internalError) { - if (this.aborted) { - error = internalError; - } - } - - callback(error); - } - - async flushHeaders() { - if (this[kFlushedHeaders] || this.destroyed) { - return; - } - - this[kFlushedHeaders] = true; - - const isConnectMethod = this.method === HTTP2_METHOD_CONNECT; - - // The real magic is here - const onStream = stream => { - this._request = stream; - - if (this.destroyed) { - stream.destroy(); - return; - } - - // Forwards `timeout`, `continue`, `close` and `error` events to this instance. - if (!isConnectMethod) { - // TODO: Should we proxy `close` here? - proxyEvents(stream, this, ['timeout', 'continue']); - } - - stream.once('error', error => { - this.destroy(error); - }); - - stream.once('aborted', () => { - const {res} = this; - if (res) { - res.aborted = true; - res.emit('aborted'); - res.destroy(); - } else { - this.destroy(new Error('The server aborted the HTTP/2 stream')); - } - }); - - const onResponse = (headers, flags, rawHeaders) => { - // If we were to emit raw request stream, it would be as fast as the native approach. - // Note that wrapping the raw stream in a Proxy instance won't improve the performance (already tested it). - const response = new IncomingMessage(this.socket, stream.readableHighWaterMark); - this.res = response; - - // Undocumented, but it is used by `cacheable-request` - response.url = `${this[kOrigin].origin}${this.path}`; - - response.req = this; - response.statusCode = headers[HTTP2_HEADER_STATUS]; - response.headers = headers; - response.rawHeaders = rawHeaders; - - response.once('end', () => { - response.complete = true; - - // Has no effect, just be consistent with the Node.js behavior - response.socket = null; - response.connection = null; - }); - - if (isConnectMethod) { - response.upgrade = true; - - // The HTTP1 API says the socket is detached here, - // but we can't do that so we pass the original HTTP2 request. - if (this.emit('connect', response, stream, Buffer.alloc(0))) { - this.emit('close'); - } else { - // No listeners attached, destroy the original request. - stream.destroy(); - } - } else { - // Forwards data - stream.on('data', chunk => { - if (!response._dumped && !response.push(chunk)) { - stream.pause(); - } - }); - - stream.once('end', () => { - if (!this.aborted) { - response.push(null); - } - }); - - if (!this.emit('response', response)) { - // No listeners attached, dump the response. - response._dump(); - } - } - }; - - // This event tells we are ready to listen for the data. - stream.once('response', onResponse); - - // Emits `information` event - stream.once('headers', headers => this.emit('information', {statusCode: headers[HTTP2_HEADER_STATUS]})); - - stream.once('trailers', (trailers, flags, rawTrailers) => { - const {res} = this; - - // https://github.com/nodejs/node/issues/41251 - if (res === null) { - onResponse(trailers, flags, rawTrailers); - return; - } - - // Assigns trailers to the response object. - res.trailers = trailers; - res.rawTrailers = rawTrailers; - }); - - stream.once('close', () => { - const {aborted, res} = this; - if (res) { - if (aborted) { - res.aborted = true; - res.emit('aborted'); - res.destroy(); - } - - const finish = () => { - res.emit('close'); - - this.destroy(); - this.emit('close'); - }; - - if (res.readable) { - res.once('end', finish); - } else { - finish(); - } - - return; - } - - if (!this.destroyed) { - this.destroy(new Error('The HTTP/2 stream has been early terminated')); - this.emit('close'); - return; - } - - this.destroy(); - this.emit('close'); - }); - - this.socket = new Proxy(stream, proxySocketHandler); - - for (const job of this[kJobs]) { - job(); - } - - this[kJobs].length = 0; - - this.emit('socket', this.socket); - }; - - if (!(HTTP2_HEADER_AUTHORITY in this[kHeaders]) && !isConnectMethod) { - this[kHeaders][HTTP2_HEADER_AUTHORITY] = this[kOrigin].host; - } - - // Makes a HTTP2 request - if (this[kSession]) { - try { - onStream(this[kSession].request(this[kHeaders])); - } catch (error) { - this.destroy(error); - } - } else { - this.reusedSocket = true; - - try { - const promise = this.agent.request(this[kOrigin], this[kOptions], this[kHeaders]); - this[kPendingAgentPromise] = promise; - - onStream(await promise); - - this[kPendingAgentPromise] = false; - } catch (error) { - this[kPendingAgentPromise] = false; - - this.destroy(error); - } - } - } - - get connection() { - return this.socket; - } - - set connection(value) { - this.socket = value; - } - - getHeaderNames() { - return Object.keys(this[kHeaders]); - } - - hasHeader(name) { - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } - - return Boolean(this[kHeaders][name.toLowerCase()]); - } - - getHeader(name) { - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } - - return this[kHeaders][name.toLowerCase()]; - } - - get headersSent() { - return this[kFlushedHeaders]; - } - - removeHeader(name) { - if (typeof name !== 'string') { - throw new ERR_INVALID_ARG_TYPE('name', 'string', name); - } - - if (this.headersSent) { - throw new ERR_HTTP_HEADERS_SENT('remove'); - } - - delete this[kHeaders][name.toLowerCase()]; - } - - setHeader(name, value) { - if (this.headersSent) { - throw new ERR_HTTP_HEADERS_SENT('set'); - } - - validateHeaderName(name); - validateHeaderValue(name, value); - - const lowercased = name.toLowerCase(); - - if (lowercased === 'connection') { - if (value.toLowerCase() === 'keep-alive') { - return; - } - - throw new Error(`Invalid 'connection' header: ${value}`); - } - - if (lowercased === 'host' && this.method === 'CONNECT') { - this[kHeaders][HTTP2_HEADER_AUTHORITY] = value; - } else { - this[kHeaders][lowercased] = value; - } - } - - setNoDelay() { - // HTTP2 sockets cannot be malformed, do nothing. - } - - setSocketKeepAlive() { - // HTTP2 sockets cannot be malformed, do nothing. - } - - setTimeout(ms, callback) { - const applyTimeout = () => this._request.setTimeout(ms, callback); - - if (this._request) { - applyTimeout(); - } else { - this[kJobs].push(applyTimeout); - } - - return this; - } - - get maxHeadersCount() { - if (!this.destroyed && this._request) { - return this._request.session.localSettings.maxHeaderListSize; - } - - return undefined; - } - - set maxHeadersCount(_value) { - // Updating HTTP2 settings would affect all requests, do nothing. - } -} - -module.exports = ClientRequest; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/incoming-message.js b/includes/external/addressbook/node_modules/http2-wrapper/source/incoming-message.js deleted file mode 100644 index 780e051..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/incoming-message.js +++ /dev/null @@ -1,73 +0,0 @@ -'use strict'; -const {Readable} = require('stream'); - -class IncomingMessage extends Readable { - constructor(socket, highWaterMark) { - super({ - emitClose: false, - autoDestroy: true, - highWaterMark - }); - - this.statusCode = null; - this.statusMessage = ''; - this.httpVersion = '2.0'; - this.httpVersionMajor = 2; - this.httpVersionMinor = 0; - this.headers = {}; - this.trailers = {}; - this.req = null; - - this.aborted = false; - this.complete = false; - this.upgrade = null; - - this.rawHeaders = []; - this.rawTrailers = []; - - this.socket = socket; - - this._dumped = false; - } - - get connection() { - return this.socket; - } - - set connection(value) { - this.socket = value; - } - - _destroy(error, callback) { - if (!this.readableEnded) { - this.aborted = true; - } - - // See https://github.com/nodejs/node/issues/35303 - callback(); - - this.req._request.destroy(error); - } - - setTimeout(ms, callback) { - this.req.setTimeout(ms, callback); - return this; - } - - _dump() { - if (!this._dumped) { - this._dumped = true; - - this.removeAllListeners('data'); - this.resume(); - } - } - - _read() { - if (this.req) { - this.req._request.resume(); - } - } -} - -module.exports = IncomingMessage; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/index.js b/includes/external/addressbook/node_modules/http2-wrapper/source/index.js deleted file mode 100644 index 7a2a49c..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/index.js +++ /dev/null @@ -1,50 +0,0 @@ -'use strict'; -const http2 = require('http2'); -const { - Agent, - globalAgent -} = require('./agent.js'); -const ClientRequest = require('./client-request.js'); -const IncomingMessage = require('./incoming-message.js'); -const auto = require('./auto.js'); -const { - HttpOverHttp2, - HttpsOverHttp2 -} = require('./proxies/h1-over-h2.js'); -const Http2OverHttp2 = require('./proxies/h2-over-h2.js'); -const { - Http2OverHttp, - Http2OverHttps -} = require('./proxies/h2-over-h1.js'); -const validateHeaderName = require('./utils/validate-header-name.js'); -const validateHeaderValue = require('./utils/validate-header-value.js'); - -const request = (url, options, callback) => new ClientRequest(url, options, callback); - -const get = (url, options, callback) => { - // eslint-disable-next-line unicorn/prevent-abbreviations - const req = new ClientRequest(url, options, callback); - req.end(); - - return req; -}; - -module.exports = { - ...http2, - ClientRequest, - IncomingMessage, - Agent, - globalAgent, - request, - get, - auto, - proxies: { - HttpOverHttp2, - HttpsOverHttp2, - Http2OverHttp2, - Http2OverHttp, - Http2OverHttps - }, - validateHeaderName, - validateHeaderValue -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/get-auth-headers.js b/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/get-auth-headers.js deleted file mode 100644 index 364a858..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/get-auth-headers.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; - -module.exports = self => { - const {username, password} = self.proxyOptions.url; - - if (username || password) { - const data = `${username}:${password}`; - const authorization = `Basic ${Buffer.from(data).toString('base64')}`; - - return { - 'proxy-authorization': authorization, - authorization - }; - } - - return {}; -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h1-over-h2.js b/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h1-over-h2.js deleted file mode 100644 index 15a4f78..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h1-over-h2.js +++ /dev/null @@ -1,90 +0,0 @@ -'use strict'; -const tls = require('tls'); -const http = require('http'); -const https = require('https'); -const JSStreamSocket = require('../utils/js-stream-socket.js'); -const {globalAgent} = require('../agent.js'); -const UnexpectedStatusCodeError = require('./unexpected-status-code-error.js'); -const initialize = require('./initialize.js'); -const getAuthorizationHeaders = require('./get-auth-headers.js'); - -const createConnection = (self, options, callback) => { - (async () => { - try { - const {proxyOptions} = self; - const {url, headers, raw} = proxyOptions; - - const stream = await globalAgent.request(url, proxyOptions, { - ...getAuthorizationHeaders(self), - ...headers, - ':method': 'CONNECT', - ':authority': `${options.host}:${options.port}` - }); - - stream.once('error', callback); - stream.once('response', headers => { - const statusCode = headers[':status']; - - if (statusCode !== 200) { - callback(new UnexpectedStatusCodeError(statusCode, '')); - return; - } - - const encrypted = self instanceof https.Agent; - - if (raw && encrypted) { - options.socket = stream; - const secureStream = tls.connect(options); - - secureStream.once('close', () => { - stream.destroy(); - }); - - callback(null, secureStream); - return; - } - - const socket = new JSStreamSocket(stream); - socket.encrypted = false; - socket._handle.getpeername = out => { - out.family = undefined; - out.address = undefined; - out.port = undefined; - }; - - callback(null, socket); - }); - } catch (error) { - callback(error); - } - })(); -}; - -class HttpOverHttp2 extends http.Agent { - constructor(options) { - super(options); - - initialize(this, options.proxyOptions); - } - - createConnection(options, callback) { - createConnection(this, options, callback); - } -} - -class HttpsOverHttp2 extends https.Agent { - constructor(options) { - super(options); - - initialize(this, options.proxyOptions); - } - - createConnection(options, callback) { - createConnection(this, options, callback); - } -} - -module.exports = { - HttpOverHttp2, - HttpsOverHttp2 -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-h1.js b/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-h1.js deleted file mode 100644 index 8764f07..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-h1.js +++ /dev/null @@ -1,48 +0,0 @@ -'use strict'; -const http = require('http'); -const https = require('https'); -const Http2OverHttpX = require('./h2-over-hx.js'); -const getAuthorizationHeaders = require('./get-auth-headers.js'); - -const getStream = request => new Promise((resolve, reject) => { - const onConnect = (response, socket, head) => { - socket.unshift(head); - - request.off('error', reject); - resolve([socket, response.statusCode, response.statusMessage]); - }; - - request.once('error', reject); - request.once('connect', onConnect); -}); - -class Http2OverHttp extends Http2OverHttpX { - async _getProxyStream(authority) { - const {proxyOptions} = this; - const {url, headers} = this.proxyOptions; - - const network = url.protocol === 'https:' ? https : http; - - // `new URL('https://localhost/httpbin.org:443')` results in - // a `/httpbin.org:443` path, which has an invalid leading slash. - const request = network.request({ - ...proxyOptions, - hostname: url.hostname, - port: url.port, - path: authority, - headers: { - ...getAuthorizationHeaders(this), - ...headers, - host: authority - }, - method: 'CONNECT' - }).end(); - - return getStream(request); - } -} - -module.exports = { - Http2OverHttp, - Http2OverHttps: Http2OverHttp -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-h2.js b/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-h2.js deleted file mode 100644 index 414c5e9..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-h2.js +++ /dev/null @@ -1,32 +0,0 @@ -'use strict'; -const {globalAgent} = require('../agent.js'); -const Http2OverHttpX = require('./h2-over-hx.js'); -const getAuthorizationHeaders = require('./get-auth-headers.js'); - -const getStatusCode = stream => new Promise((resolve, reject) => { - stream.once('error', reject); - stream.once('response', headers => { - stream.off('error', reject); - resolve(headers[':status']); - }); -}); - -class Http2OverHttp2 extends Http2OverHttpX { - async _getProxyStream(authority) { - const {proxyOptions} = this; - - const headers = { - ...getAuthorizationHeaders(this), - ...proxyOptions.headers, - ':method': 'CONNECT', - ':authority': authority - }; - - const stream = await globalAgent.request(proxyOptions.url, proxyOptions, headers); - const statusCode = await getStatusCode(stream); - - return [stream, statusCode, '']; - } -} - -module.exports = Http2OverHttp2; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-hx.js b/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-hx.js deleted file mode 100644 index 0f5a104..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/h2-over-hx.js +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; -const {Agent} = require('../agent.js'); -const JSStreamSocket = require('../utils/js-stream-socket.js'); -const UnexpectedStatusCodeError = require('./unexpected-status-code-error.js'); -const initialize = require('./initialize.js'); - -class Http2OverHttpX extends Agent { - constructor(options) { - super(options); - - initialize(this, options.proxyOptions); - } - - async createConnection(origin, options) { - const authority = `${origin.hostname}:${origin.port || 443}`; - - const [stream, statusCode, statusMessage] = await this._getProxyStream(authority); - if (statusCode !== 200) { - throw new UnexpectedStatusCodeError(statusCode, statusMessage); - } - - if (this.proxyOptions.raw) { - options.socket = stream; - } else { - const socket = new JSStreamSocket(stream); - socket.encrypted = false; - socket._handle.getpeername = out => { - out.family = undefined; - out.address = undefined; - out.port = undefined; - }; - - return socket; - } - - return super.createConnection(origin, options); - } -} - -module.exports = Http2OverHttpX; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/initialize.js b/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/initialize.js deleted file mode 100644 index e4c5889..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/initialize.js +++ /dev/null @@ -1,21 +0,0 @@ -'use strict'; -// See https://github.com/facebook/jest/issues/2549 -// eslint-disable-next-line node/prefer-global/url -const {URL} = require('url'); -const checkType = require('../utils/check-type.js'); - -module.exports = (self, proxyOptions) => { - checkType('proxyOptions', proxyOptions, ['object']); - checkType('proxyOptions.headers', proxyOptions.headers, ['object', 'undefined']); - checkType('proxyOptions.raw', proxyOptions.raw, ['boolean', 'undefined']); - checkType('proxyOptions.url', proxyOptions.url, [URL, 'string']); - - const url = new URL(proxyOptions.url); - - self.proxyOptions = { - raw: true, - ...proxyOptions, - headers: {...proxyOptions.headers}, - url - }; -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/unexpected-status-code-error.js b/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/unexpected-status-code-error.js deleted file mode 100644 index c7f0216..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/proxies/unexpected-status-code-error.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; - -class UnexpectedStatusCodeError extends Error { - constructor(statusCode, statusMessage = '') { - super(`The proxy server rejected the request with status code ${statusCode} (${statusMessage || 'empty status message'})`); - this.statusCode = statusCode; - this.statusMessage = statusMessage; - } -} - -module.exports = UnexpectedStatusCodeError; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/calculate-server-name.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/calculate-server-name.js deleted file mode 100644 index a8ba061..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/calculate-server-name.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; -const {isIP} = require('net'); -const assert = require('assert'); - -const getHost = host => { - if (host[0] === '[') { - const idx = host.indexOf(']'); - - assert(idx !== -1); - return host.slice(1, idx); - } - - const idx = host.indexOf(':'); - if (idx === -1) { - return host; - } - - return host.slice(0, idx); -}; - -module.exports = host => { - const servername = getHost(host); - - if (isIP(servername)) { - return ''; - } - - return servername; -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/check-type.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/check-type.js deleted file mode 100644 index ddfefdc..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/check-type.js +++ /dev/null @@ -1,20 +0,0 @@ -'use strict'; - -const checkType = (name, value, types) => { - const valid = types.some(type => { - const typeofType = typeof type; - if (typeofType === 'string') { - return typeof value === type; - } - - return value instanceof type; - }); - - if (!valid) { - const names = types.map(type => typeof type === 'string' ? type : type.name); - - throw new TypeError(`Expected '${name}' to be a type of ${names.join(' or ')}, got ${typeof value}`); - } -}; - -module.exports = checkType; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/delay-async-destroy.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/delay-async-destroy.js deleted file mode 100644 index 53d81cf..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/delay-async-destroy.js +++ /dev/null @@ -1,33 +0,0 @@ -'use strict'; - -module.exports = stream => { - if (stream.listenerCount('error') !== 0) { - return stream; - } - - stream.__destroy = stream._destroy; - stream._destroy = (...args) => { - const callback = args.pop(); - - stream.__destroy(...args, async error => { - await Promise.resolve(); - callback(error); - }); - }; - - const onError = error => { - // eslint-disable-next-line promise/prefer-await-to-then - Promise.resolve().then(() => { - stream.emit('error', error); - }); - }; - - stream.once('error', onError); - - // eslint-disable-next-line promise/prefer-await-to-then - Promise.resolve().then(() => { - stream.off('error', onError); - }); - - return stream; -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/errors.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/errors.js deleted file mode 100644 index 7be9e6b..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/errors.js +++ /dev/null @@ -1,51 +0,0 @@ -'use strict'; -/* istanbul ignore file: https://github.com/nodejs/node/blob/master/lib/internal/errors.js */ - -const makeError = (Base, key, getMessage) => { - module.exports[key] = class NodeError extends Base { - constructor(...args) { - super(typeof getMessage === 'string' ? getMessage : getMessage(args)); - this.name = `${super.name} [${key}]`; - this.code = key; - } - }; -}; - -makeError(TypeError, 'ERR_INVALID_ARG_TYPE', args => { - const type = args[0].includes('.') ? 'property' : 'argument'; - - let valid = args[1]; - const isManyTypes = Array.isArray(valid); - - if (isManyTypes) { - valid = `${valid.slice(0, -1).join(', ')} or ${valid.slice(-1)}`; - } - - return `The "${args[0]}" ${type} must be ${isManyTypes ? 'one of' : 'of'} type ${valid}. Received ${typeof args[2]}`; -}); - -makeError(TypeError, 'ERR_INVALID_PROTOCOL', args => - `Protocol "${args[0]}" not supported. Expected "${args[1]}"` -); - -makeError(Error, 'ERR_HTTP_HEADERS_SENT', args => - `Cannot ${args[0]} headers after they are sent to the client` -); - -makeError(TypeError, 'ERR_INVALID_HTTP_TOKEN', args => - `${args[0]} must be a valid HTTP token [${args[1]}]` -); - -makeError(TypeError, 'ERR_HTTP_INVALID_HEADER_VALUE', args => - `Invalid value "${args[0]} for header "${args[1]}"` -); - -makeError(TypeError, 'ERR_INVALID_CHAR', args => - `Invalid character in ${args[0]} [${args[1]}]` -); - -makeError( - Error, - 'ERR_HTTP2_NO_SOCKET_MANIPULATION', - 'HTTP/2 sockets should not be directly manipulated (e.g. read and written)' -); diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/is-request-pseudo-header.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/is-request-pseudo-header.js deleted file mode 100644 index bed31cd..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/is-request-pseudo-header.js +++ /dev/null @@ -1,13 +0,0 @@ -'use strict'; - -module.exports = header => { - switch (header) { - case ':method': - case ':scheme': - case ':authority': - case ':path': - return true; - default: - return false; - } -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/js-stream-socket.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/js-stream-socket.js deleted file mode 100644 index ac22280..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/js-stream-socket.js +++ /dev/null @@ -1,8 +0,0 @@ -'use strict'; -const stream = require('stream'); -const tls = require('tls'); - -// Really awesome hack. -const JSStreamSocket = (new tls.TLSSocket(new stream.PassThrough()))._handle._parentWrap.constructor; - -module.exports = JSStreamSocket; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/proxy-events.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/proxy-events.js deleted file mode 100644 index 35e2ae0..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/proxy-events.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = (from, to, events) => { - for (const event of events) { - from.on(event, (...args) => to.emit(event, ...args)); - } -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/proxy-socket-handler.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/proxy-socket-handler.js deleted file mode 100644 index 89a0ac4..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/proxy-socket-handler.js +++ /dev/null @@ -1,102 +0,0 @@ -'use strict'; -const {ERR_HTTP2_NO_SOCKET_MANIPULATION} = require('./errors.js'); - -/* istanbul ignore file */ -/* https://github.com/nodejs/node/blob/6eec858f34a40ffa489c1ec54bb24da72a28c781/lib/internal/http2/compat.js#L195-L272 */ - -const proxySocketHandler = { - has(stream, property) { - // Replaced [kSocket] with .socket - const reference = stream.session === undefined ? stream : stream.session.socket; - return (property in stream) || (property in reference); - }, - - get(stream, property) { - switch (property) { - case 'on': - case 'once': - case 'end': - case 'emit': - case 'destroy': - return stream[property].bind(stream); - case 'writable': - case 'destroyed': - return stream[property]; - case 'readable': - if (stream.destroyed) { - return false; - } - - return stream.readable; - case 'setTimeout': { - const {session} = stream; - if (session !== undefined) { - return session.setTimeout.bind(session); - } - - return stream.setTimeout.bind(stream); - } - - case 'write': - case 'read': - case 'pause': - case 'resume': - throw new ERR_HTTP2_NO_SOCKET_MANIPULATION(); - default: { - // Replaced [kSocket] with .socket - const reference = stream.session === undefined ? stream : stream.session.socket; - const value = reference[property]; - - return typeof value === 'function' ? value.bind(reference) : value; - } - } - }, - - getPrototypeOf(stream) { - if (stream.session !== undefined) { - // Replaced [kSocket] with .socket - return Reflect.getPrototypeOf(stream.session.socket); - } - - return Reflect.getPrototypeOf(stream); - }, - - set(stream, property, value) { - switch (property) { - case 'writable': - case 'readable': - case 'destroyed': - case 'on': - case 'once': - case 'end': - case 'emit': - case 'destroy': - stream[property] = value; - return true; - case 'setTimeout': { - const {session} = stream; - if (session === undefined) { - stream.setTimeout = value; - } else { - session.setTimeout = value; - } - - return true; - } - - case 'write': - case 'read': - case 'pause': - case 'resume': - throw new ERR_HTTP2_NO_SOCKET_MANIPULATION(); - default: { - // Replaced [kSocket] with .socket - const reference = stream.session === undefined ? stream : stream.session.socket; - reference[property] = value; - return true; - } - } - } -}; - -module.exports = proxySocketHandler; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/validate-header-name.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/validate-header-name.js deleted file mode 100644 index 82cbc34..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/validate-header-name.js +++ /dev/null @@ -1,11 +0,0 @@ -'use strict'; -const {ERR_INVALID_HTTP_TOKEN} = require('./errors.js'); -const isRequestPseudoHeader = require('./is-request-pseudo-header.js'); - -const isValidHttpToken = /^[\^`\-\w!#$%&*+.|~]+$/; - -module.exports = name => { - if (typeof name !== 'string' || (!isValidHttpToken.test(name) && !isRequestPseudoHeader(name))) { - throw new ERR_INVALID_HTTP_TOKEN('Header name', name); - } -}; diff --git a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/validate-header-value.js b/includes/external/addressbook/node_modules/http2-wrapper/source/utils/validate-header-value.js deleted file mode 100644 index 749c985..0000000 --- a/includes/external/addressbook/node_modules/http2-wrapper/source/utils/validate-header-value.js +++ /dev/null @@ -1,17 +0,0 @@ -'use strict'; -const { - ERR_HTTP_INVALID_HEADER_VALUE, - ERR_INVALID_CHAR -} = require('./errors.js'); - -const isInvalidHeaderValue = /[^\t\u0020-\u007E\u0080-\u00FF]/; - -module.exports = (name, value) => { - if (typeof value === 'undefined') { - throw new ERR_HTTP_INVALID_HEADER_VALUE(value, name); - } - - if (isInvalidHeaderValue.test(value)) { - throw new ERR_INVALID_CHAR('header content', name); - } -}; |