summaryrefslogtreecommitdiff
path: root/node_modules/http2-wrapper
diff options
context:
space:
mode:
Diffstat (limited to 'node_modules/http2-wrapper')
-rw-r--r--node_modules/http2-wrapper/LICENSE21
-rw-r--r--node_modules/http2-wrapper/README.md470
-rw-r--r--node_modules/http2-wrapper/package.json54
-rw-r--r--node_modules/http2-wrapper/source/agent.js670
-rw-r--r--node_modules/http2-wrapper/source/auto.js149
-rw-r--r--node_modules/http2-wrapper/source/client-request.js445
-rw-r--r--node_modules/http2-wrapper/source/incoming-message.js58
-rw-r--r--node_modules/http2-wrapper/source/index.js28
-rw-r--r--node_modules/http2-wrapper/source/utils/calculate-server-name.js27
-rw-r--r--node_modules/http2-wrapper/source/utils/errors.js45
-rw-r--r--node_modules/http2-wrapper/source/utils/is-request-pseudo-header.js13
-rw-r--r--node_modules/http2-wrapper/source/utils/proxy-events.js7
-rw-r--r--node_modules/http2-wrapper/source/utils/url-to-options.js25
13 files changed, 0 insertions, 2012 deletions
diff --git a/node_modules/http2-wrapper/LICENSE b/node_modules/http2-wrapper/LICENSE
deleted file mode 100644
index 15ad2e8..0000000
--- a/node_modules/http2-wrapper/LICENSE
+++ /dev/null
@@ -1,21 +0,0 @@
-MIT License
-
-Copyright (c) 2018 Szymon Marczak
-
-Permission is hereby granted, free of charge, to any person obtaining a copy
-of this software and associated documentation files (the "Software"), to deal
-in the Software without restriction, including without limitation the rights
-to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the Software is
-furnished to do so, subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
diff --git a/node_modules/http2-wrapper/README.md b/node_modules/http2-wrapper/README.md
deleted file mode 100644
index 09b5f48..0000000
--- a/node_modules/http2-wrapper/README.md
+++ /dev/null
@@ -1,470 +0,0 @@
-# http2-wrapper
-> HTTP/2 client, just with the familiar `https` API
-
-[![Node CI](https://github.com/szmarczak/http2-wrapper/workflows/Node%20CI/badge.svg)](https://github.com/szmarczak/http2-wrapper/actions)
-[![codecov](https://codecov.io/gh/szmarczak/http2-wrapper/branch/master/graph/badge.svg)](https://codecov.io/gh/szmarczak/http2-wrapper)
-[![npm](https://img.shields.io/npm/dm/http2-wrapper.svg)](https://www.npmjs.com/package/http2-wrapper)
-[![install size](https://packagephobia.now.sh/badge?p=http2-wrapper)](https://packagephobia.now.sh/result?p=http2-wrapper)
-
-This package was created to support HTTP/2 without the need to rewrite your code.<br>
-I recommend adapting to the [`http2`](https://nodejs.org/api/http2.html) module if possible - it's much simpler to use and has many cool features!
-
-**Tip**: `http2-wrapper` is very useful when you rely on other modules that use the HTTP/1 API and you want to support HTTP/2.
-
-**Pro Tip**: While the native `http2` doesn't have agents yet, you can use `http2-wrapper` Agents and still operate on the native HTTP/2 streams.
-
-## Installation
-
-> `$ npm install http2-wrapper`<br>
-> `$ yarn add http2-wrapper`
-
-## Usage
-```js
-const http2 = require('http2-wrapper');
-
-const options = {
- hostname: 'nghttp2.org',
- protocol: 'https:',
- path: '/httpbin/post',
- method: 'POST',
- headers: {
- 'content-length': 6
- }
-};
-
-const request = http2.request(options, response => {
- console.log('statusCode:', response.statusCode);
- console.log('headers:', response.headers);
-
- const body = [];
- response.on('data', chunk => {
- body.push(chunk);
- });
- response.on('end', () => {
- console.log('body:', Buffer.concat(body).toString());
- });
-});
-
-request.on('error', console.error);
-
-request.write('123');
-request.end('456');
-
-// statusCode: 200
-// headers: [Object: null prototype] {
-// ':status': 200,
-// date: 'Fri, 27 Sep 2019 19:45:46 GMT',
-// 'content-type': 'application/json',
-// 'access-control-allow-origin': '*',
-// 'access-control-allow-credentials': 'true',
-// 'content-length': '239',
-// 'x-backend-header-rtt': '0.002516',
-// 'strict-transport-security': 'max-age=31536000',
-// server: 'nghttpx',
-// via: '1.1 nghttpx',
-// 'alt-svc': 'h3-23=":4433"; ma=3600',
-// 'x-frame-options': 'SAMEORIGIN',
-// 'x-xss-protection': '1; mode=block',
-// 'x-content-type-options': 'nosniff'
-// }
-// body: {
-// "args": {},
-// "data": "123456",
-// "files": {},
-// "form": {},
-// "headers": {
-// "Content-Length": "6",
-// "Host": "nghttp2.org"
-// },
-// "json": 123456,
-// "origin": "xxx.xxx.xxx.xxx",
-// "url": "https://nghttp2.org/httpbin/post"
-// }
-```
-
-## API
-
-**Note:** The `session` option was renamed to `tlsSession` for better readability.
-
-### http2.auto(url, options, callback)
-
-Performs [ALPN](https://nodejs.org/api/tls.html#tls_alpn_and_sni) negotiation.
-Returns a Promise giving proper `ClientRequest` instance (depending on the ALPN).
-
-**Note**: The `agent` option represents an object with `http`, `https` and `http2` properties.
-
-```js
-const http2 = require('http2-wrapper');
-
-const options = {
- hostname: 'httpbin.org',
- protocol: 'http:', // Note the `http:` protocol here
- path: '/post',
- method: 'POST',
- headers: {
- 'content-length': 6
- }
-};
-
-(async () => {
- try {
- const request = await http2.auto(options, response => {
- console.log('statusCode:', response.statusCode);
- console.log('headers:', response.headers);
-
- const body = [];
- response.on('data', chunk => body.push(chunk));
- response.on('end', () => {
- console.log('body:', Buffer.concat(body).toString());
- });
- });
-
- request.on('error', console.error);
-
- request.write('123');
- request.end('456');
- } catch (error) {
- console.error(error);
- }
-})();
-
-// statusCode: 200
-// headers: { connection: 'close',
-// server: 'gunicorn/19.9.0',
-// date: 'Sat, 15 Dec 2018 18:19:32 GMT',
-// 'content-type': 'application/json',
-// 'content-length': '259',
-// 'access-control-allow-origin': '*',
-// 'access-control-allow-credentials': 'true',
-// via: '1.1 vegur' }
-// body: {
-// "args": {},
-// "data": "123456",
-// "files": {},
-// "form": {},
-// "headers": {
-// "Connection": "close",
-// "Content-Length": "6",
-// "Host": "httpbin.org"
-// },
-// "json": 123456,
-// "origin": "xxx.xxx.xxx.xxx",
-// "url": "http://httpbin.org/post"
-// }
-```
-
-### http2.auto.protocolCache
-
-An instance of [`quick-lru`](https://github.com/sindresorhus/quick-lru) used for ALPN cache.
-
-There is a maximum of 100 entries. You can modify the limit through `protocolCache.maxSize` - note that the change will be visible globally.
-
-### http2.request(url, options, callback)
-
-Same as [`https.request`](https://nodejs.org/api/https.html#https_https_request_options_callback).
-
-##### options.h2session
-
-Type: `Http2Session`<br>
-
-The session used to make the actual request. If none provided, it will use `options.agent`.
-
-### http2.get(url, options, callback)
-
-Same as [`https.get`](https://nodejs.org/api/https.html#https_https_get_options_callback).
-
-### new http2.ClientRequest(url, options, callback)
-
-Same as [`https.ClientRequest`](https://nodejs.org/api/https.html#https_class_https_clientrequest).
-
-### new http2.IncomingMessage(socket)
-
-Same as [`https.IncomingMessage`](https://nodejs.org/api/https.html#https_class_https_incomingmessage).
-
-### new http2.Agent(options)
-
-**Note:** this is **not** compatible with the classic `http.Agent`.
-
-Usage example:
-
-```js
-const http2 = require('http2-wrapper');
-
-class MyAgent extends http2.Agent {
- createConnection(origin, options) {
- console.log(`Connecting to ${http2.Agent.normalizeOrigin(origin)}`);
- return http2.Agent.connect(origin, options);
- }
-}
-
-http2.get({
- hostname: 'google.com',
- agent: new MyAgent()
-}, res => {
- res.on('data', chunk => console.log(`Received chunk of ${chunk.length} bytes`));
-});
-```
-
-#### options
-
-Each option is assigned to each `Agent` instance and can be changed later.
-
-##### timeout
-
-Type: `number`<br>
-Default: `60000`
-
-If there's no activity after `timeout` milliseconds, the session will be closed.
-
-##### maxSessions
-
-Type: `number`<br>
-Default: `Infinity`
-
-The maximum amount of sessions in total.
-
-##### maxFreeSessions
-
-Type: `number`<br>
-Default: `10`
-
-The maximum amount of free sessions in total. This only applies to sessions with no pending requests.
-
-**Note:** It is possible that the amount will be exceeded when sessions have at least 1 pending request.
-
-##### maxCachedTlsSessions
-
-Type: `number`<br>
-Default: `100`
-
-The maximum amount of cached TLS sessions.
-
-#### Agent.normalizeOrigin(url)
-
-Returns a string representing the origin of the URL.
-
-#### agent.settings
-
-Type: `object`<br>
-Default: `{enablePush: false}`
-
-[Settings](https://nodejs.org/api/http2.html#http2_settings_object) used by the current agent instance.
-
-#### agent.normalizeOptions([options](https://github.com/szmarczak/http2-wrapper/blob/master/source/agent.js))
-
-Returns a string representing normalized options.
-
-```js
-Agent.normalizeOptions({servername: 'example.com'});
-// => ':example.com'
-```
-
-#### agent.getSession(origin, options)
-
-##### [origin](https://nodejs.org/api/http2.html#http2_http2_connect_authority_options_listener)
-
-Type: `string` `URL` `object`
-
-An origin used to create new session.
-
-##### [options](https://nodejs.org/api/http2.html#http2_http2_connect_authority_options_listener)
-
-Type: `object`
-
-The options used to create new session.
-
-Returns a Promise giving free `Http2Session`. If no free sessions are found, a new one is created.
-
-#### agent.getSession([origin](#origin), [options](options-1), listener)
-
-##### listener
-
-Type: `object`
-
-```
-{
- reject: error => void,
- resolve: session => void
-}
-```
-
-If the `listener` argument is present, the Promise will resolve immediately. It will use the `resolve` function to pass the session.
-
-#### agent.request([origin](#origin), [options](#options-1), [headers](https://nodejs.org/api/http2.html#http2_headers_object), [streamOptions](https://nodejs.org/api/http2.html#http2_clienthttp2session_request_headers_options))
-
-Returns a Promise giving `Http2Stream`.
-
-#### agent.createConnection([origin](#origin), [options](#options-1))
-
-Returns a new `TLSSocket`. It defaults to `Agent.connect(origin, options)`.
-
-#### agent.closeFreeSessions()
-
-Makes an attempt to close free sessions. Only sessions with 0 concurrent streams will be closed.
-
-#### agent.destroy(reason)
-
-Destroys **all** sessions.
-
-#### Event: 'session'
-
-```js
-agent.on('session', session => {
- // A new session has been created by the Agent.
-});
-```
-
-## Proxy support
-
-An example of a full-featured proxy server can be found [here](examples/proxy/server.js). It supports **mirroring, custom authorities and the CONNECT protocol**.
-
-### Mirroring
-
-To mirror another server we need to use only [`http2-proxy`](https://github.com/nxtedition/node-http2-proxy). We don't need the CONNECT protocol or custom authorities.
-
-To see the result, just navigate to the server's address.
-
-### HTTP/1 over HTTP/2
-
-Since we don't care about mirroring, the server needs to support the CONNECT protocol in this case.
-
-The client looks like this:
-
-```js
-const https = require('https');
-const http2 = require('http2');
-
-const session = http2.connect('https://localhost:8000', {
- // For demo purposes only!
- rejectUnauthorized: false
-});
-
-session.ref();
-
-https.request('https://httpbin.org/anything', {
- createConnection: options => {
- return session.request({
- ':method': 'CONNECT',
- ':authority': `${options.host}:${options.port}`
- });
- }
-}, response => {
- console.log('statusCode:', response.statusCode);
- console.log('headers:', response.headers);
-
- const body = [];
- response.on('data', chunk => {
- body.push(chunk);
- });
- response.on('end', () => {
- console.log('body:', Buffer.concat(body).toString());
-
- session.unref();
- });
-}).end();
-```
-
-### HTTP/2 over HTTP/2
-
-It's a tricky one! We cannot create an HTTP/2 session on top of an HTTP/2 stream. But... we can still specify the `:authority` header, no need to use the CONNECT protocol here.
-
-The client looks like this:
-
-```js
-const http2 = require('../../source');
-const {Agent} = http2;
-
-class ProxyAgent extends Agent {
- constructor(url, options) {
- super(options);
-
- this.origin = url;
- }
-
- request(origin, sessionOptions, headers, streamOptions) {
- return super.request(this.origin, sessionOptions, {
- ...headers,
- ':authority': (new URL(origin)).host
- }, streamOptions);
- }
-}
-
-const request = http2.request({
- hostname: 'httpbin.org',
- protocol: 'https:',
- path: '/anything',
- agent: new ProxyAgent('https://localhost:8000'),
- // For demo purposes only!
- rejectUnauthorized: false
-}, response => {
- console.log('statusCode:', response.statusCode);
- console.log('headers:', response.headers);
-
- const body = [];
- response.on('data', chunk => {
- body.push(chunk);
- });
- response.on('end', () => {
- console.log('body:', Buffer.concat(body).toString());
- });
-});
-
-request.on('error', console.error);
-
-request.end();
-```
-
-## Notes
-
- - If you're interested in [WebSockets over HTTP/2](https://tools.ietf.org/html/rfc8441), then [check out this discussion](https://github.com/websockets/ws/issues/1458).
- - [HTTP/2 sockets cannot be malformed](https://github.com/nodejs/node/blob/cc8250fab86486632fdeb63892be735d7628cd13/lib/internal/http2/core.js#L725), therefore modifying the socket will have no effect.
- - You can make [a custom Agent](examples/push-stream/index.js) to support push streams.
-
-## Benchmarks
-
-CPU: Intel i7-7700k (governor: performance)<br>
-Server: H2O v2.2.5 [`h2o.conf`](h2o.conf)<br>
-Node: v14.5.0
-Linux: 5.6.18-156.current
-
-`auto` means `http2wrapper.auto`.
-
-```
-http2-wrapper x 12,181 ops/sec ±3.39% (75 runs sampled)
-http2-wrapper - preconfigured session x 13,140 ops/sec ±2.51% (79 runs sampled)
-http2-wrapper - auto x 11,412 ops/sec ±2.55% (78 runs sampled)
-http2 x 16,050 ops/sec ±1.39% (86 runs sampled)
-https - auto - keepalive x 12,288 ops/sec ±2.69% (79 runs sampled)
-https - keepalive x 12,155 ops/sec ±3.32% (78 runs sampled)
-https x 1,604 ops/sec ±2.03% (77 runs sampled)
-http x 6,041 ops/sec ±3.82% (76 runs sampled)
-Fastest is http2
-```
-
-`http2-wrapper`:
-- 32% **less** performant than `http2`
-- as performant as `https - keepalive`
-- 100% **more** performant than `http`
-
-`http2-wrapper - preconfigured session`:
-- 22% **less** performant than `http2`
-- 8% **more** performant than `https - keepalive`
-- 118% **more** performant than `http`
-
-`http2-wrapper - auto`:
-- 41% **less** performant than `http2`
-- 8% **less** performant than `https - keepalive`
-- 89% **more** performant than `http`
-
-`https - auto - keepalive`:
-- 31% **less** performant than `http2`
-- as performant as `https - keepalive`
-- 103% **more** performant than `http`
-
-## Related
-
- - [`got`](https://github.com/sindresorhus/got) - Simplified HTTP requests
-
-## License
-
-MIT
diff --git a/node_modules/http2-wrapper/package.json b/node_modules/http2-wrapper/package.json
deleted file mode 100644
index d47894f..0000000
--- a/node_modules/http2-wrapper/package.json
+++ /dev/null
@@ -1,54 +0,0 @@
-{
- "name": "http2-wrapper",
- "version": "1.0.3",
- "description": "HTTP2 client, just with the familiar `https` API",
- "main": "source",
- "engines": {
- "node": ">=10.19.0"
- },
- "scripts": {
- "test": "xo && nyc --reporter=lcovonly --reporter=text --reporter=html ava"
- },
- "files": [
- "source"
- ],
- "keywords": [
- "http2",
- "https",
- "http",
- "request"
- ],
- "repository": {
- "type": "git",
- "url": "git+https://github.com/szmarczak/http2-wrapper.git"
- },
- "author": "Szymon Marczak",
- "license": "MIT",
- "bugs": {
- "url": "https://github.com/szmarczak/http2-wrapper/issues"
- },
- "homepage": "https://github.com/szmarczak/http2-wrapper#readme",
- "dependencies": {
- "quick-lru": "^5.1.1",
- "resolve-alpn": "^1.0.0"
- },
- "devDependencies": {
- "@sindresorhus/is": "^3.0.0",
- "ava": "^3.10.1",
- "benchmark": "^2.1.4",
- "get-stream": "^5.1.0",
- "got": "^11.5.0",
- "http2-proxy": "^5.0.51",
- "lolex": "^6.0.0",
- "many-keys-map": "^1.0.2",
- "nyc": "^15.1.0",
- "p-event": "^4.2.0",
- "tempy": "^0.5.0",
- "to-readable-stream": "^2.1.0",
- "tsd": "^0.13.1",
- "xo": "^0.32.1"
- },
- "ava": {
- "timeout": "2m"
- }
-}
diff --git a/node_modules/http2-wrapper/source/agent.js b/node_modules/http2-wrapper/source/agent.js
deleted file mode 100644
index b2b1cff..0000000
--- a/node_modules/http2-wrapper/source/agent.js
+++ /dev/null
@@ -1,670 +0,0 @@
-'use strict';
-const EventEmitter = require('events');
-const tls = require('tls');
-const http2 = require('http2');
-const QuickLRU = require('quick-lru');
-
-const kCurrentStreamsCount = Symbol('currentStreamsCount');
-const kRequest = Symbol('request');
-const kOriginSet = Symbol('cachedOriginSet');
-const kGracefullyClosing = Symbol('gracefullyClosing');
-
-const nameKeys = [
- // `http2.connect()` options
- 'maxDeflateDynamicTableSize',
- 'maxSessionMemory',
- 'maxHeaderListPairs',
- 'maxOutstandingPings',
- 'maxReservedRemoteStreams',
- 'maxSendHeaderBlockLength',
- 'paddingStrategy',
-
- // `tls.connect()` options
- 'localAddress',
- 'path',
- 'rejectUnauthorized',
- 'minDHSize',
-
- // `tls.createSecureContext()` options
- 'ca',
- 'cert',
- 'clientCertEngine',
- 'ciphers',
- 'key',
- 'pfx',
- 'servername',
- 'minVersion',
- 'maxVersion',
- 'secureProtocol',
- 'crl',
- 'honorCipherOrder',
- 'ecdhCurve',
- 'dhparam',
- 'secureOptions',
- 'sessionIdContext'
-];
-
-const getSortedIndex = (array, value, compare) => {
- let low = 0;
- let high = array.length;
-
- while (low < high) {
- const mid = (low + high) >>> 1;
-
- /* istanbul ignore next */
- if (compare(array[mid], value)) {
- // This never gets called because we use descending sort. Better to have this anyway.
- low = mid + 1;
- } else {
- high = mid;
- }
- }
-
- return low;
-};
-
-const compareSessions = (a, b) => {
- return 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 (const coveredSession of where) {
- if (
- // 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[kCurrentStreamsCount] + session[kCurrentStreamsCount] <= 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 (const session of where) {
- if (
- coveredSession[kOriginSet].length < session[kOriginSet].length &&
- coveredSession[kOriginSet].every(origin => session[kOriginSet].includes(origin)) &&
- coveredSession[kCurrentStreamsCount] + session[kCurrentStreamsCount] <= session.remoteSettings.maxConcurrentStreams
- ) {
- gracefullyClose(coveredSession);
- }
- }
-};
-
-const getSessions = ({agent, isFree}) => {
- const result = {};
-
- // eslint-disable-next-line guard-for-in
- for (const normalizedOptions in agent.sessions) {
- const sessions = agent.sessions[normalizedOptions];
-
- const filtered = sessions.filter(session => {
- const result = session[Agent.kCurrentStreamsCount] < session.remoteSettings.maxConcurrentStreams;
-
- return isFree ? result : !result;
- });
-
- if (filtered.length !== 0) {
- result[normalizedOptions] = filtered;
- }
- }
-
- return result;
-};
-
-const gracefullyClose = session => {
- session[kGracefullyClosing] = true;
-
- if (session[kCurrentStreamsCount] === 0) {
- session.close();
- }
-};
-
-class Agent extends EventEmitter {
- constructor({timeout = 60000, maxSessions = Infinity, maxFreeSessions = 10, maxCachedTlsSessions = 100} = {}) {
- super();
-
- // A session is considered busy when its current streams count
- // is equal to or greater than the `maxConcurrentStreams` value.
-
- // A session is considered free when its current streams count
- // is less than the `maxConcurrentStreams` value.
-
- // SESSIONS[NORMALIZED_OPTIONS] = [];
- this.sessions = {};
-
- // The queue for creating new sessions. It looks like this:
- // QUEUE[NORMALIZED_OPTIONS][NORMALIZED_ORIGIN] = ENTRY_FUNCTION
- //
- // 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 free sessions in total
- // TODO: decreasing `maxFreeSessions` should close some sessions
- this.maxFreeSessions = maxFreeSessions;
-
- this._freeSessionsCount = 0;
- this._sessionsCount = 0;
-
- // We don't support push streams by default.
- this.settings = {
- enablePush: false
- };
-
- // Reusing TLS sessions increases performance.
- this.tlsSessionCache = new QuickLRU({maxSize: maxCachedTlsSessions});
- }
-
- static normalizeOrigin(url, servername) {
- if (typeof url === 'string') {
- url = new URL(url);
- }
-
- if (servername && url.hostname !== servername) {
- url.hostname = servername;
- }
-
- return url.origin;
- }
-
- normalizeOptions(options) {
- let normalized = '';
-
- if (options) {
- for (const key of nameKeys) {
- if (options[key]) {
- normalized += `:${options[key]}`;
- }
- }
- }
-
- return normalized;
- }
-
- _tryToCreateNewSession(normalizedOptions, normalizedOrigin) {
- if (!(normalizedOptions in this.queue) || !(normalizedOrigin in this.queue[normalizedOptions])) {
- return;
- }
-
- const item = this.queue[normalizedOptions][normalizedOrigin];
-
- // The entry function can be run only once.
- // BUG: The session may be never created when:
- // - the first condition is false AND
- // - this function is never called with the same arguments in the future.
- if (this._sessionsCount < this.maxSessions && !item.completed) {
- item.completed = true;
-
- item();
- }
- }
-
- getSession(origin, options, listeners) {
- return new Promise((resolve, reject) => {
- if (Array.isArray(listeners)) {
- 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}];
- }
-
- const normalizedOptions = this.normalizeOptions(options);
- const normalizedOrigin = Agent.normalizeOrigin(origin, options && options.servername);
-
- if (normalizedOrigin === undefined) {
- for (const {reject} of listeners) {
- reject(new TypeError('The `origin` argument needs to be a string or an URL object'));
- }
-
- return;
- }
-
- 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.
- for (const session of sessions) {
- const sessionMaxConcurrentStreams = session.remoteSettings.maxConcurrentStreams;
-
- if (sessionMaxConcurrentStreams < maxConcurrentStreams) {
- break;
- }
-
- if (session[kOriginSet].includes(normalizedOrigin)) {
- const sessionCurrentStreamsCount = session[kCurrentStreamsCount];
-
- 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;
- }
-
- // We're looking for the session which has biggest current pending stream count,
- // in order to minimalize the amount of active sessions.
- if (sessionCurrentStreamsCount > currentStreamsCount) {
- optimalSession = session;
- currentStreamsCount = sessionCurrentStreamsCount;
- }
- }
- }
-
- if (optimalSession) {
- /* istanbul ignore next: safety check */
- if (listeners.length !== 1) {
- for (const {reject} of listeners) {
- const error = new Error(
- `Expected the length of listeners to be 1, got ${listeners.length}.\n` +
- 'Please report this to https://github.com/szmarczak/http2-wrapper/'
- );
-
- reject(error);
- }
-
- return;
- }
-
- listeners[0].resolve(optimalSession);
- 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);
-
- // This shouldn't be executed here.
- // See the comment inside _tryToCreateNewSession.
- this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
- return;
- }
- } else {
- this.queue[normalizedOptions] = {};
- }
-
- // 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 (Object.keys(this.queue[normalizedOptions]).length === 0) {
- delete this.queue[normalizedOptions];
- }
- }
- };
-
- // The main logic is here
- const entry = () => {
- const name = `${normalizedOrigin}:${normalizedOptions}`;
- let receivedSettings = false;
-
- try {
- const session = http2.connect(origin, {
- createConnection: this.createConnection,
- settings: this.settings,
- session: this.tlsSessionCache.get(name),
- ...options
- });
- session[kCurrentStreamsCount] = 0;
- session[kGracefullyClosing] = false;
-
- const isFree = () => session[kCurrentStreamsCount] < session.remoteSettings.maxConcurrentStreams;
- let wasFree = true;
-
- session.socket.once('session', tlsSession => {
- this.tlsSessionCache.set(name, tlsSession);
- });
-
- session.once('error', error => {
- // Listeners are empty when the session successfully connected.
- for (const {reject} of listeners) {
- reject(error);
- }
-
- // The connection got broken, purge the cache.
- this.tlsSessionCache.delete(name);
- });
-
- session.setTimeout(this.timeout, () => {
- // Terminates all streams owned by this session.
- // TODO: Maybe the streams should have a "Session timed out" error?
- session.destroy();
- });
-
- session.once('close', () => {
- if (receivedSettings) {
- // 1. If it wasn't free then no need to decrease because
- // it has been decreased already in session.request().
- // 2. `stream.once('close')` won't increment the count
- // because the session is already closed.
- if (wasFree) {
- this._freeSessionsCount--;
- }
-
- this._sessionsCount--;
-
- // 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];
- where.splice(where.indexOf(session), 1);
-
- if (where.length === 0) {
- delete this.sessions[normalizedOptions];
- }
- } else {
- // Broken connection
- const error = new Error('Session closed without receiving a SETTINGS frame');
- error.code = 'HTTP2WRAPPER_NOSETTINGS';
-
- for (const {reject} of listeners) {
- reject(error);
- }
-
- removeFromQueue();
- }
-
- // There may be another session awaiting.
- this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
- });
-
- // Iterates over the queue and processes listeners.
- const processListeners = () => {
- if (!(normalizedOptions in this.queue) || !isFree()) {
- return;
- }
-
- for (const origin of session[kOriginSet]) {
- if (origin in this.queue[normalizedOptions]) {
- const {listeners} = this.queue[normalizedOptions][origin];
-
- // Prevents session overloading.
- while (listeners.length !== 0 && isFree()) {
- // We assume `resolve(...)` calls `request(...)` *directly*,
- // otherwise the session will get overloaded.
- listeners.shift().resolve(session);
- }
-
- const where = this.queue[normalizedOptions];
- if (where[origin].listeners.length === 0) {
- delete where[origin];
-
- if (Object.keys(where).length === 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] = session.originSet;
-
- if (!isFree()) {
- // The session is full.
- return;
- }
-
- processListeners();
-
- // Close covered sessions (if possible).
- closeCoveredSessions(this.sessions[normalizedOptions], session);
- });
-
- session.once('remoteSettings', () => {
- // Fix Node.js bug preventing the process from exiting
- session.ref();
- session.unref();
-
- this._sessionsCount++;
-
- // The Agent could have been destroyed already.
- if (entry.destroyed) {
- const error = new Error('Agent has been destroyed');
-
- for (const listener of listeners) {
- listener.reject(error);
- }
-
- session.destroy();
- return;
- }
-
- session[kOriginSet] = session.originSet;
-
- {
- const where = this.sessions;
-
- if (normalizedOptions in where) {
- const sessions = where[normalizedOptions];
- sessions.splice(getSortedIndex(sessions, session, compareSessions), 0, session);
- } else {
- where[normalizedOptions] = [session];
- }
- }
-
- this._freeSessionsCount += 1;
- receivedSettings = true;
-
- this.emit('session', session);
-
- processListeners();
- removeFromQueue();
-
- // TODO: Close last recently used (or least used?) session
- if (session[kCurrentStreamsCount] === 0 && this._freeSessionsCount > this.maxFreeSessions) {
- session.close();
- }
-
- // Check if we haven't managed to execute all listeners.
- if (listeners.length !== 0) {
- // Request for a new session with predefined listeners.
- this.getSession(normalizedOrigin, options, listeners);
- listeners.length = 0;
- }
-
- // `session.remoteSettings.maxConcurrentStreams` might get increased
- session.on('remoteSettings', () => {
- processListeners();
-
- // 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();
-
- ++session[kCurrentStreamsCount];
-
- if (session[kCurrentStreamsCount] === session.remoteSettings.maxConcurrentStreams) {
- this._freeSessionsCount--;
- }
-
- stream.once('close', () => {
- wasFree = isFree();
-
- --session[kCurrentStreamsCount];
-
- if (!session.destroyed && !session.closed) {
- closeSessionIfCovered(this.sessions[normalizedOptions], session);
-
- if (isFree() && !session.closed) {
- if (!wasFree) {
- this._freeSessionsCount++;
-
- wasFree = true;
- }
-
- const isEmpty = session[kCurrentStreamsCount] === 0;
-
- if (isEmpty) {
- session.unref();
- }
-
- if (
- isEmpty &&
- (
- this._freeSessionsCount > this.maxFreeSessions ||
- session[kGracefullyClosing]
- )
- ) {
- session.close();
- } else {
- closeCoveredSessions(this.sessions[normalizedOptions], session);
- processListeners();
- }
- }
- }
- });
-
- return stream;
- };
- } catch (error) {
- for (const listener of listeners) {
- listener.reject(error);
- }
-
- removeFromQueue();
- }
- };
-
- entry.listeners = listeners;
- entry.completed = false;
- entry.destroyed = false;
-
- this.queue[normalizedOptions][normalizedOrigin] = entry;
- this._tryToCreateNewSession(normalizedOptions, normalizedOrigin);
- });
- }
-
- request(origin, options, headers, streamOptions) {
- return new Promise((resolve, reject) => {
- this.getSession(origin, options, [{
- reject,
- resolve: session => {
- try {
- resolve(session.request(headers, streamOptions));
- } catch (error) {
- reject(error);
- }
- }
- }]);
- });
- }
-
- createConnection(origin, options) {
- return Agent.connect(origin, options);
- }
-
- static connect(origin, options) {
- options.ALPNProtocols = ['h2'];
-
- const port = origin.port || 443;
- const host = origin.hostname || origin.host;
-
- if (typeof options.servername === 'undefined') {
- options.servername = host;
- }
-
- return tls.connect(port, host, options);
- }
-
- closeFreeSessions() {
- for (const sessions of Object.values(this.sessions)) {
- for (const session of sessions) {
- if (session[kCurrentStreamsCount] === 0) {
- session.close();
- }
- }
- }
- }
-
- destroy(reason) {
- for (const sessions of Object.values(this.sessions)) {
- for (const session of sessions) {
- session.destroy(reason);
- }
- }
-
- for (const entriesOfAuthority of Object.values(this.queue)) {
- for (const entry of Object.values(entriesOfAuthority)) {
- entry.destroyed = true;
- }
- }
-
- // New requests should NOT attach to destroyed sessions
- this.queue = {};
- }
-
- get freeSessions() {
- return getSessions({agent: this, isFree: true});
- }
-
- get busySessions() {
- return getSessions({agent: this, isFree: false});
- }
-}
-
-Agent.kCurrentStreamsCount = kCurrentStreamsCount;
-Agent.kGracefullyClosing = kGracefullyClosing;
-
-module.exports = {
- Agent,
- globalAgent: new Agent()
-};
diff --git a/node_modules/http2-wrapper/source/auto.js b/node_modules/http2-wrapper/source/auto.js
deleted file mode 100644
index af4e9ba..0000000
--- a/node_modules/http2-wrapper/source/auto.js
+++ /dev/null
@@ -1,149 +0,0 @@
-'use strict';
-const http = require('http');
-const https = require('https');
-const resolveALPN = require('resolve-alpn');
-const QuickLRU = require('quick-lru');
-const Http2ClientRequest = require('./client-request');
-const calculateServerName = require('./utils/calculate-server-name');
-const urlToOptions = require('./utils/url-to-options');
-
-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 onRemove = () => {
- agent.removeSocket(socket, options);
- socket.off('close', onClose);
- socket.off('free', onFree);
- socket.off('agentRemove', onRemove);
- };
-
- socket.on('agentRemove', onRemove);
-
- agent.emit('free', socket, options);
-};
-
-const resolveProtocol = 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 result.alpnProtocol;
- }
-
- const {path, agent} = options;
- options.path = options.socketPath;
-
- const resultPromise = resolveALPN(options);
- queue.set(name, resultPromise);
-
- try {
- const {socket, alpnProtocol} = await resultPromise;
- cache.set(name, alpnProtocol);
-
- options.path = path;
-
- if (alpnProtocol === 'h2') {
- // https://github.com/nodejs/node/issues/33343
- socket.destroy();
- } else {
- const {globalAgent} = https;
- const defaultCreateConnection = https.Agent.prototype.createConnection;
-
- if (agent) {
- if (agent.createConnection === defaultCreateConnection) {
- installSocket(agent, socket, options);
- } else {
- socket.destroy();
- }
- } else if (globalAgent.createConnection === defaultCreateConnection) {
- installSocket(globalAgent, socket, options);
- } else {
- socket.destroy();
- }
- }
-
- queue.delete(name);
-
- return alpnProtocol;
- } catch (error) {
- queue.delete(name);
-
- throw error;
- }
- }
-
- return cache.get(name);
-};
-
-module.exports = async (input, options, callback) => {
- if (typeof input === 'string' || input instanceof URL) {
- input = urlToOptions(new URL(input));
- }
-
- if (typeof options === 'function') {
- callback = options;
- options = undefined;
- }
-
- options = {
- ALPNProtocols: ['h2', 'http/1.1'],
- ...input,
- ...options,
- resolveSocket: true
- };
-
- 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);
- options.port = options.port || (isHttps ? 443 : 80);
- options._defaultAgent = isHttps ? https.globalAgent : http.globalAgent;
-
- const agents = options.agent;
-
- if (agents) {
- if (agents.addRequest) {
- throw new Error('The `options.agent` object can contain only `http`, `https` or `http2` properties');
- }
-
- options.agent = agents[isHttps ? 'https' : 'http'];
- }
-
- if (isHttps) {
- const protocol = await resolveProtocol(options);
-
- if (protocol === 'h2') {
- if (agents) {
- options.agent = agents.http2;
- }
-
- return new Http2ClientRequest(options, callback);
- }
- }
-
- return http.request(options, callback);
-};
-
-module.exports.protocolCache = cache;
diff --git a/node_modules/http2-wrapper/source/client-request.js b/node_modules/http2-wrapper/source/client-request.js
deleted file mode 100644
index b712967..0000000
--- a/node_modules/http2-wrapper/source/client-request.js
+++ /dev/null
@@ -1,445 +0,0 @@
-'use strict';
-const http2 = require('http2');
-const {Writable} = require('stream');
-const {Agent, globalAgent} = require('./agent');
-const IncomingMessage = require('./incoming-message');
-const urlToOptions = require('./utils/url-to-options');
-const proxyEvents = require('./utils/proxy-events');
-const isRequestPseudoHeader = require('./utils/is-request-pseudo-header');
-const {
- ERR_INVALID_ARG_TYPE,
- ERR_INVALID_PROTOCOL,
- ERR_HTTP_HEADERS_SENT,
- ERR_INVALID_HTTP_TOKEN,
- ERR_HTTP_INVALID_HEADER_VALUE,
- ERR_INVALID_CHAR
-} = require('./utils/errors');
-
-const {
- HTTP2_HEADER_STATUS,
- HTTP2_HEADER_METHOD,
- HTTP2_HEADER_PATH,
- 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 isValidHttpToken = /^[\^`\-\w!#$%&*+.|~]+$/;
-const isInvalidHeaderValue = /[^\t\u0020-\u007E\u0080-\u00FF]/;
-
-class ClientRequest extends Writable {
- constructor(input, options, callback) {
- super({
- autoDestroy: false
- });
-
- const hasInput = typeof input === 'string' || input instanceof URL;
- if (hasInput) {
- input = urlToOptions(input instanceof URL ? input : new URL(input));
- }
-
- if (typeof options === 'function' || options === undefined) {
- // (options, callback)
- callback = options;
- options = hasInput ? input : {...input};
- } else {
- // (input, options, callback)
- options = {...input, ...options};
- }
-
- if (options.h2session) {
- this[kSession] = options.h2session;
- } else if (options.agent === false) {
- this.agent = new Agent({maxFreeSessions: 0});
- } else if (typeof options.agent === 'undefined' || options.agent === null) {
- if (typeof options.createConnection === 'function') {
- // This is a workaround - we don't have to create the session on our own.
- this.agent = new Agent({maxFreeSessions: 0});
- this.agent.createConnection = options.createConnection;
- } else {
- this.agent = globalAgent;
- }
- } else if (typeof options.agent.request === 'function') {
- this.agent = options.agent;
- } else {
- throw new ERR_INVALID_ARG_TYPE('options.agent', ['Agent-like Object', 'undefined', 'false'], options.agent);
- }
-
- if (options.protocol && options.protocol !== 'https:') {
- throw new ERR_INVALID_PROTOCOL(options.protocol, 'https:');
- }
-
- const port = options.port || options.defaultPort || (this.agent && this.agent.defaultPort) || 443;
- const host = options.hostname || options.host || 'localhost';
-
- // Don't enforce the origin via options. It may be changed in an Agent.
- delete options.hostname;
- delete options.host;
- delete options.port;
-
- const {timeout} = options;
- options.timeout = undefined;
-
- this[kHeaders] = Object.create(null);
- this[kJobs] = [];
-
- this.socket = null;
- this.connection = null;
-
- this.method = options.method || 'GET';
- this.path = options.path;
-
- this.res = null;
- this.aborted = false;
- this.reusedSocket = false;
-
- if (options.headers) {
- for (const [header, value] of Object.entries(options.headers)) {
- this.setHeader(header, value);
- }
- }
-
- 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.
- if (port === 443) {
- this[kOrigin] = `https://${host}`;
-
- if (!(':authority' in this[kHeaders])) {
- this[kHeaders][':authority'] = host;
- }
- } else {
- this[kOrigin] = `https://${host}:${port}`;
-
- if (!(':authority' in this[kHeaders])) {
- this[kHeaders][':authority'] = `${host}:${port}`;
- }
- }
-
- 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() {
- return this[kHeaders][HTTP2_HEADER_PATH];
- }
-
- set path(value) {
- if (value) {
- this[kHeaders][HTTP2_HEADER_PATH] = value;
- }
- }
-
- 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) {
- if (this.destroyed) {
- return;
- }
-
- this.flushHeaders();
-
- const callEnd = () => {
- // For GET, HEAD and DELETE
- if (this._mustNotHaveABody) {
- 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();
- }
-
- _destroy(error, callback) {
- if (this.res) {
- this.res._dump();
- }
-
- if (this._request) {
- this._request.destroy();
- }
-
- 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) {
- proxyEvents(stream, this, ['timeout', 'continue', 'close', 'error']);
- }
-
- // Wait for the `finish` event. We don't want to emit the `response` event
- // before `request.end()` is called.
- const waitForEnd = fn => {
- return (...args) => {
- if (!this.writable && !this.destroyed) {
- fn(...args);
- } else {
- this.once('finish', () => {
- fn(...args);
- });
- }
- };
- };
-
- // This event tells we are ready to listen for the data.
- stream.once('response', waitForEnd((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;
-
- response.req = this;
- response.statusCode = headers[HTTP2_HEADER_STATUS];
- response.headers = headers;
- response.rawHeaders = rawHeaders;
-
- response.once('end', () => {
- if (this.aborted) {
- response.aborted = true;
- response.emit('aborted');
- } else {
- 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', () => {
- response.push(null);
- });
-
- if (!this.emit('response', response)) {
- // No listeners attached, dump the response.
- response._dump();
- }
- }
- }));
-
- // Emits `information` event
- stream.once('headers', waitForEnd(
- headers => this.emit('information', {statusCode: headers[HTTP2_HEADER_STATUS]})
- ));
-
- stream.once('trailers', waitForEnd((trailers, flags, rawTrailers) => {
- const {res} = this;
-
- // Assigns trailers to the response object.
- res.trailers = trailers;
- res.rawTrailers = rawTrailers;
- }));
-
- const {socket} = stream.session;
- this.socket = socket;
- this.connection = socket;
-
- for (const job of this[kJobs]) {
- job();
- }
-
- this.emit('socket', this.socket);
- };
-
- // Makes a HTTP2 request
- if (this[kSession]) {
- try {
- onStream(this[kSession].request(this[kHeaders]));
- } catch (error) {
- this.emit('error', error);
- }
- } else {
- this.reusedSocket = true;
-
- try {
- onStream(await this.agent.request(this[kOrigin], this[kOptions], this[kHeaders]));
- } catch (error) {
- this.emit('error', error);
- }
- }
- }
-
- 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');
- }
-
- if (typeof name !== 'string' || (!isValidHttpToken.test(name) && !isRequestPseudoHeader(name))) {
- throw new ERR_INVALID_HTTP_TOKEN('Header name', name);
- }
-
- 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);
- }
-
- this[kHeaders][name.toLowerCase()] = 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/node_modules/http2-wrapper/source/incoming-message.js b/node_modules/http2-wrapper/source/incoming-message.js
deleted file mode 100644
index 7d5c0d3..0000000
--- a/node_modules/http2-wrapper/source/incoming-message.js
+++ /dev/null
@@ -1,58 +0,0 @@
-'use strict';
-const {Readable} = require('stream');
-
-class IncomingMessage extends Readable {
- constructor(socket, highWaterMark) {
- super({
- highWaterMark,
- autoDestroy: false
- });
-
- 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.connection = socket;
-
- this._dumped = false;
- }
-
- _destroy(error) {
- 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/node_modules/http2-wrapper/source/index.js b/node_modules/http2-wrapper/source/index.js
deleted file mode 100644
index fb83349..0000000
--- a/node_modules/http2-wrapper/source/index.js
+++ /dev/null
@@ -1,28 +0,0 @@
-'use strict';
-const http2 = require('http2');
-const agent = require('./agent');
-const ClientRequest = require('./client-request');
-const IncomingMessage = require('./incoming-message');
-const auto = require('./auto');
-
-const request = (url, options, callback) => {
- return 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,
- request,
- get,
- auto
-};
diff --git a/node_modules/http2-wrapper/source/utils/calculate-server-name.js b/node_modules/http2-wrapper/source/utils/calculate-server-name.js
deleted file mode 100644
index b05c099..0000000
--- a/node_modules/http2-wrapper/source/utils/calculate-server-name.js
+++ /dev/null
@@ -1,27 +0,0 @@
-'use strict';
-const net = require('net');
-/* istanbul ignore file: https://github.com/nodejs/node/blob/v13.0.1/lib/_http_agent.js */
-
-module.exports = options => {
- let servername = options.host;
- const hostHeader = options.headers && options.headers.host;
-
- if (hostHeader) {
- if (hostHeader.startsWith('[')) {
- const index = hostHeader.indexOf(']');
- if (index === -1) {
- servername = hostHeader;
- } else {
- servername = hostHeader.slice(1, -1);
- }
- } else {
- servername = hostHeader.split(':', 1)[0];
- }
- }
-
- if (net.isIP(servername)) {
- return '';
- }
-
- return servername;
-};
diff --git a/node_modules/http2-wrapper/source/utils/errors.js b/node_modules/http2-wrapper/source/utils/errors.js
deleted file mode 100644
index 5018283..0000000
--- a/node_modules/http2-wrapper/source/utils/errors.js
+++ /dev/null
@@ -1,45 +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 => {
- return `Protocol "${args[0]}" not supported. Expected "${args[1]}"`;
-});
-
-makeError(Error, 'ERR_HTTP_HEADERS_SENT', args => {
- return `Cannot ${args[0]} headers after they are sent to the client`;
-});
-
-makeError(TypeError, 'ERR_INVALID_HTTP_TOKEN', args => {
- return `${args[0]} must be a valid HTTP token [${args[1]}]`;
-});
-
-makeError(TypeError, 'ERR_HTTP_INVALID_HEADER_VALUE', args => {
- return `Invalid value "${args[0]} for header "${args[1]}"`;
-});
-
-makeError(TypeError, 'ERR_INVALID_CHAR', args => {
- return `Invalid character in ${args[0]} [${args[1]}]`;
-});
diff --git a/node_modules/http2-wrapper/source/utils/is-request-pseudo-header.js b/node_modules/http2-wrapper/source/utils/is-request-pseudo-header.js
deleted file mode 100644
index bed31cd..0000000
--- a/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/node_modules/http2-wrapper/source/utils/proxy-events.js b/node_modules/http2-wrapper/source/utils/proxy-events.js
deleted file mode 100644
index 35e2ae0..0000000
--- a/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/node_modules/http2-wrapper/source/utils/url-to-options.js b/node_modules/http2-wrapper/source/utils/url-to-options.js
deleted file mode 100644
index 36d1580..0000000
--- a/node_modules/http2-wrapper/source/utils/url-to-options.js
+++ /dev/null
@@ -1,25 +0,0 @@
-'use strict';
-/* istanbul ignore file: https://github.com/nodejs/node/blob/a91293d4d9ab403046ab5eb022332e4e3d249bd3/lib/internal/url.js#L1257 */
-
-module.exports = url => {
- const options = {
- protocol: url.protocol,
- hostname: typeof url.hostname === 'string' && url.hostname.startsWith('[') ? url.hostname.slice(1, -1) : url.hostname,
- host: url.host,
- hash: url.hash,
- search: url.search,
- pathname: url.pathname,
- href: url.href,
- path: `${url.pathname || ''}${url.search || ''}`
- };
-
- if (typeof url.port === 'string' && url.port.length !== 0) {
- options.port = Number(url.port);
- }
-
- if (url.username || url.password) {
- options.auth = `${url.username || ''}:${url.password || ''}`;
- }
-
- return options;
-};