Index: node_modules/agentkeepalive/LICENSE
===================================================================
--- node_modules/agentkeepalive/LICENSE	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/LICENSE	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,23 @@
+The MIT License
+
+Copyright(c) node-modules and other contributors.
+Copyright(c) 2012 - 2015 fengmk2 <fengmk2@gmail.com>
+
+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.
Index: node_modules/agentkeepalive/README.md
===================================================================
--- node_modules/agentkeepalive/README.md	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/README.md	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,256 @@
+# agentkeepalive
+
+[![NPM version][npm-image]][npm-url]
+[![Known Vulnerabilities][snyk-image]][snyk-url]
+[![Node.js CI](https://github.com/node-modules/agentkeepalive/actions/workflows/nodejs.yml/badge.svg)](https://github.com/node-modules/agentkeepalive/actions/workflows/nodejs.yml)
+[![npm download][download-image]][download-url]
+
+[npm-image]: https://img.shields.io/npm/v/agentkeepalive.svg?style=flat
+[npm-url]: https://npmjs.org/package/agentkeepalive
+[snyk-image]: https://snyk.io/test/npm/agentkeepalive/badge.svg?style=flat-square
+[snyk-url]: https://snyk.io/test/npm/agentkeepalive
+[download-image]: https://img.shields.io/npm/dm/agentkeepalive.svg?style=flat-square
+[download-url]: https://npmjs.org/package/agentkeepalive
+
+The enhancement features `keep alive` `http.Agent`. Support `http` and `https`.
+
+## What's different from original `http.Agent`?
+
+- `keepAlive=true` by default
+- Disable Nagle's algorithm: `socket.setNoDelay(true)`
+- Add free socket timeout: avoid long time inactivity socket leak in the free-sockets queue.
+- Add active socket timeout: avoid long time inactivity socket leak in the active-sockets queue.
+- TTL for active socket.
+
+## Node.js version required
+
+Support Node.js >= `8.0.0`
+
+## Install
+
+```bash
+$ npm install agentkeepalive --save
+```
+
+## new Agent([options])
+
+* `options` {Object} Set of configurable options to set on the agent.
+  Can have the following fields:
+  * `keepAlive` {Boolean} Keep sockets around in a pool to be used by
+    other requests in the future. Default = `true`.
+  * `keepAliveMsecs` {Number} When using the keepAlive option, specifies the initial delay
+    for TCP Keep-Alive packets. Ignored when the keepAlive option is false or undefined. Defaults to 1000.
+    Default = `1000`.  Only relevant if `keepAlive` is set to `true`.
+  * `freeSocketTimeout`: {Number} Sets the free socket to timeout
+    after `freeSocketTimeout` milliseconds of inactivity on the free socket.
+    The default [server-side timeout](https://nodejs.org/api/http.html#serverkeepalivetimeout) is 5000 milliseconds, to [avoid ECONNRESET exceptions](https://medium.com/ssense-tech/reduce-networking-errors-in-nodejs-23b4eb9f2d83), we set the default value to `4000` milliseconds.
+    Only relevant if `keepAlive` is set to `true`.
+  * `timeout`: {Number} Sets the working socket to timeout
+    after `timeout` milliseconds of inactivity on the working socket.
+    Default is `freeSocketTimeout * 2` so long as that value is greater than or equal to 8 seconds, otherwise the default is 8 seconds.
+  * `maxSockets` {Number} Maximum number of sockets to allow per
+    host. Default = `Infinity`.
+  * `maxFreeSockets` {Number} Maximum number of sockets (per host) to leave open
+    in a free state. Only relevant if `keepAlive` is set to `true`.
+    Default = `256`.
+  * `socketActiveTTL` {Number} Sets the socket active time to live, even if it's in use.
+    If not set, the behaviour keeps the same (the socket will be released only when free)
+    Default = `null`.
+
+## Usage
+
+```js
+const http = require('http');
+const HttpAgent = require('agentkeepalive').HttpAgent;
+
+const keepaliveAgent = new HttpAgent({
+  maxSockets: 100,
+  maxFreeSockets: 10,
+  timeout: 60000, // active socket keepalive for 60 seconds
+  freeSocketTimeout: 30000, // free socket keepalive for 30 seconds
+});
+
+const options = {
+  host: 'cnodejs.org',
+  port: 80,
+  path: '/',
+  method: 'GET',
+  agent: keepaliveAgent,
+};
+
+const req = http.request(options, res => {
+  console.log('STATUS: ' + res.statusCode);
+  console.log('HEADERS: ' + JSON.stringify(res.headers));
+  res.setEncoding('utf8');
+  res.on('data', function (chunk) {
+    console.log('BODY: ' + chunk);
+  });
+});
+req.on('error', e => {
+  console.log('problem with request: ' + e.message);
+});
+req.end();
+
+setTimeout(() => {
+  if (keepaliveAgent.statusChanged) {
+    console.log('[%s] agent status changed: %j', Date(), keepaliveAgent.getCurrentStatus());
+  }
+}, 2000);
+
+```
+
+### `getter agent.statusChanged`
+
+counters have change or not after last checkpoint.
+
+### `agent.getCurrentStatus()`
+
+`agent.getCurrentStatus()` will return a object to show the status of this agent:
+
+```js
+{
+  createSocketCount: 10,
+  closeSocketCount: 5,
+  timeoutSocketCount: 0,
+  requestCount: 5,
+  freeSockets: { 'localhost:57479:': 3 },
+  sockets: { 'localhost:57479:': 5 },
+  requests: {}
+}
+```
+
+### Support `https`
+
+```js
+const https = require('https');
+const HttpsAgent = require('agentkeepalive').HttpsAgent;
+
+const keepaliveAgent = new HttpsAgent();
+// https://www.google.com/search?q=nodejs&sugexp=chrome,mod=12&sourceid=chrome&ie=UTF-8
+const options = {
+  host: 'www.google.com',
+  port: 443,
+  path: '/search?q=nodejs&sugexp=chrome,mod=12&sourceid=chrome&ie=UTF-8',
+  method: 'GET',
+  agent: keepaliveAgent,
+};
+
+const req = https.request(options, res => {
+  console.log('STATUS: ' + res.statusCode);
+  console.log('HEADERS: ' + JSON.stringify(res.headers));
+  res.setEncoding('utf8');
+  res.on('data', chunk => {
+    console.log('BODY: ' + chunk);
+  });
+});
+
+req.on('error', e => {
+  console.log('problem with request: ' + e.message);
+});
+req.end();
+
+setTimeout(() => {
+  console.log('agent status: %j', keepaliveAgent.getCurrentStatus());
+}, 2000);
+```
+
+### Support `req.reusedSocket`
+
+This agent implements the `req.reusedSocket` to determine whether a request is send through a reused socket.
+
+When server closes connection at unfortunate time ([keep-alive race](https://code-examples.net/en/q/28a8069)), the http client will throw a `ECONNRESET` error. Under this circumstance, `req.reusedSocket` is useful when we want to retry the request automatically.
+
+```js
+const http = require('http');
+const HttpAgent = require('agentkeepalive').HttpAgent;
+const agent = new HttpAgent();
+
+const req = http
+  .get('http://localhost:3000', { agent }, (res) => {
+    // ...
+  })
+  .on('error', (err) => {
+    if (req.reusedSocket && err.code === 'ECONNRESET') {
+      // retry the request or anything else...
+    }
+  })
+```
+
+This behavior is consistent with Node.js core. But through `agentkeepalive`, you can use this feature in older Node.js version.
+
+## [Benchmark](https://github.com/node-modules/agentkeepalive/tree/master/benchmark)
+
+run the benchmark:
+
+```bash
+cd benchmark
+sh start.sh
+```
+
+Intel(R) Core(TM)2 Duo CPU     P8600  @ 2.40GHz
+
+node@v0.8.9
+
+50 maxSockets, 60 concurrent, 1000 requests per concurrent, 5ms delay
+
+Keep alive agent (30 seconds):
+
+```js
+Transactions:          60000 hits
+Availability:         100.00 %
+Elapsed time:          29.70 secs
+Data transferred:        14.88 MB
+Response time:            0.03 secs
+Transaction rate:      2020.20 trans/sec
+Throughput:           0.50 MB/sec
+Concurrency:           59.84
+Successful transactions:       60000
+Failed transactions:             0
+Longest transaction:          0.15
+Shortest transaction:         0.01
+```
+
+Normal agent:
+
+```js
+Transactions:          60000 hits
+Availability:         100.00 %
+Elapsed time:          46.53 secs
+Data transferred:        14.88 MB
+Response time:            0.05 secs
+Transaction rate:      1289.49 trans/sec
+Throughput:           0.32 MB/sec
+Concurrency:           59.81
+Successful transactions:       60000
+Failed transactions:             0
+Longest transaction:          0.45
+Shortest transaction:         0.00
+```
+
+Socket created:
+
+```bash
+[proxy.js:120000] keepalive, 50 created, 60000 requestFinished, 1200 req/socket, 0 requests, 0 sockets, 0 unusedSockets, 50 timeout
+{" <10ms":662," <15ms":17825," <20ms":20552," <30ms":17646," <40ms":2315," <50ms":567," <100ms":377," <150ms":56," <200ms":0," >=200ms+":0}
+----------------------------------------------------------------
+[proxy.js:120000] normal   , 53866 created, 84260 requestFinished, 1.56 req/socket, 0 requests, 0 sockets
+{" <10ms":75," <15ms":1112," <20ms":10947," <30ms":32130," <40ms":8228," <50ms":3002," <100ms":4274," <150ms":181," <200ms":18," >=200ms+":33}
+```
+
+## License
+
+[MIT](LICENSE)
+
+<!-- GITCONTRIBUTOR_START -->
+
+## Contributors
+
+|[<img src="https://avatars.githubusercontent.com/u/156269?v=4" width="100px;"/><br/><sub><b>fengmk2</b></sub>](https://github.com/fengmk2)<br/>|[<img src="https://avatars.githubusercontent.com/u/985607?v=4" width="100px;"/><br/><sub><b>dead-horse</b></sub>](https://github.com/dead-horse)<br/>|[<img src="https://avatars.githubusercontent.com/u/5557458?v=4" width="100px;"/><br/><sub><b>AndrewLeedham</b></sub>](https://github.com/AndrewLeedham)<br/>|[<img src="https://avatars.githubusercontent.com/u/5243774?v=4" width="100px;"/><br/><sub><b>ngot</b></sub>](https://github.com/ngot)<br/>|[<img src="https://avatars.githubusercontent.com/u/25919630?v=4" width="100px;"/><br/><sub><b>wrynearson</b></sub>](https://github.com/wrynearson)<br/>|[<img src="https://avatars.githubusercontent.com/u/26738844?v=4" width="100px;"/><br/><sub><b>aaronArinder</b></sub>](https://github.com/aaronArinder)<br/>|
+| :---: | :---: | :---: | :---: | :---: | :---: |
+|[<img src="https://avatars.githubusercontent.com/u/10976983?v=4" width="100px;"/><br/><sub><b>alexpenev-s</b></sub>](https://github.com/alexpenev-s)<br/>|[<img src="https://avatars.githubusercontent.com/u/959726?v=4" width="100px;"/><br/><sub><b>blemoine</b></sub>](https://github.com/blemoine)<br/>|[<img src="https://avatars.githubusercontent.com/u/398027?v=4" width="100px;"/><br/><sub><b>bdehamer</b></sub>](https://github.com/bdehamer)<br/>|[<img src="https://avatars.githubusercontent.com/u/4985201?v=4" width="100px;"/><br/><sub><b>DylanPiercey</b></sub>](https://github.com/DylanPiercey)<br/>|[<img src="https://avatars.githubusercontent.com/u/3770250?v=4" width="100px;"/><br/><sub><b>cixel</b></sub>](https://github.com/cixel)<br/>|[<img src="https://avatars.githubusercontent.com/u/2883231?v=4" width="100px;"/><br/><sub><b>HerringtonDarkholme</b></sub>](https://github.com/HerringtonDarkholme)<br/>|
+|[<img src="https://avatars.githubusercontent.com/u/1433247?v=4" width="100px;"/><br/><sub><b>denghongcai</b></sub>](https://github.com/denghongcai)<br/>|[<img src="https://avatars.githubusercontent.com/u/1847934?v=4" width="100px;"/><br/><sub><b>kibertoad</b></sub>](https://github.com/kibertoad)<br/>|[<img src="https://avatars.githubusercontent.com/u/5236150?v=4" width="100px;"/><br/><sub><b>pangorgo</b></sub>](https://github.com/pangorgo)<br/>|[<img src="https://avatars.githubusercontent.com/u/588898?v=4" width="100px;"/><br/><sub><b>mattiash</b></sub>](https://github.com/mattiash)<br/>|[<img src="https://avatars.githubusercontent.com/u/182440?v=4" width="100px;"/><br/><sub><b>nabeelbukhari</b></sub>](https://github.com/nabeelbukhari)<br/>|[<img src="https://avatars.githubusercontent.com/u/1411117?v=4" width="100px;"/><br/><sub><b>pmalouin</b></sub>](https://github.com/pmalouin)<br/>|
+[<img src="https://avatars.githubusercontent.com/u/1404810?v=4" width="100px;"/><br/><sub><b>SimenB</b></sub>](https://github.com/SimenB)<br/>|[<img src="https://avatars.githubusercontent.com/u/2630384?v=4" width="100px;"/><br/><sub><b>vinaybedre</b></sub>](https://github.com/vinaybedre)<br/>|[<img src="https://avatars.githubusercontent.com/u/10933333?v=4" width="100px;"/><br/><sub><b>starkwang</b></sub>](https://github.com/starkwang)<br/>|[<img src="https://avatars.githubusercontent.com/u/6897780?v=4" width="100px;"/><br/><sub><b>killagu</b></sub>](https://github.com/killagu)<br/>|[<img src="https://avatars.githubusercontent.com/u/15345331?v=4" width="100px;"/><br/><sub><b>tony-gutierrez</b></sub>](https://github.com/tony-gutierrez)<br/>|[<img src="https://avatars.githubusercontent.com/u/5856440?v=4" width="100px;"/><br/><sub><b>whxaxes</b></sub>](https://github.com/whxaxes)<br/>
+
+This project follows the git-contributor [spec](https://github.com/xudafeng/git-contributor), auto updated at `Sat Aug 05 2023 02:36:31 GMT+0800`.
+
+<!-- GITCONTRIBUTOR_END -->
Index: node_modules/agentkeepalive/browser.js
===================================================================
--- node_modules/agentkeepalive/browser.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/browser.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,5 @@
+module.exports = noop;
+module.exports.HttpsAgent = noop;
+
+// Noop function for browser since native api's don't use agents.
+function noop () {}
Index: node_modules/agentkeepalive/index.d.ts
===================================================================
--- node_modules/agentkeepalive/index.d.ts	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/index.d.ts	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,69 @@
+import * as http from 'http';
+import * as https from 'https';
+import * as net from 'net';
+
+interface PlainObject {
+  [key: string]: any;
+}
+
+declare class _HttpAgent extends http.Agent {
+  constructor(opts?: AgentKeepAlive.HttpOptions);
+  readonly statusChanged: boolean;
+  createConnection(options: net.NetConnectOpts, cb?: Function): net.Socket;
+  createSocket(req: http.IncomingMessage, options: http.RequestOptions, cb: Function): void;
+  getCurrentStatus(): AgentKeepAlive.AgentStatus;
+}
+
+interface Constants {
+  CURRENT_ID: Symbol;
+  CREATE_ID: Symbol;
+  INIT_SOCKET: Symbol;
+  CREATE_HTTPS_CONNECTION: Symbol;
+  SOCKET_CREATED_TIME: Symbol;
+  SOCKET_NAME: Symbol;
+  SOCKET_REQUEST_COUNT: Symbol;
+  SOCKET_REQUEST_FINISHED_COUNT: Symbol;
+}
+
+/**
+ * @deprecated instead use `import { HttpAgent } from 'agentkeepalive'; or `const HttpAgent = require('agentkeepalive').HttpAgent;`
+ */
+declare class AgentKeepAlive extends _HttpAgent {}
+
+declare namespace AgentKeepAlive {
+  export interface AgentStatus {
+    createSocketCount: number;
+    createSocketErrorCount: number;
+    closeSocketCount: number;
+    errorSocketCount: number;
+    timeoutSocketCount: number;
+    requestCount: number;
+    freeSockets: PlainObject;
+    sockets: PlainObject;
+    requests: PlainObject;
+  }
+
+  interface CommonHttpOption {
+    keepAlive?: boolean | undefined;
+    freeSocketTimeout?: number | undefined;
+    freeSocketKeepAliveTimeout?: number | undefined;
+    timeout?: number | undefined;
+    socketActiveTTL?: number | undefined;
+  }
+
+  export interface HttpOptions extends http.AgentOptions, CommonHttpOption { }
+  export interface HttpsOptions extends https.AgentOptions, CommonHttpOption { }
+
+  export class HttpAgent extends _HttpAgent {}
+  export class HttpsAgent extends https.Agent {
+    constructor(opts?: HttpsOptions);
+    readonly statusChanged: boolean;
+    createConnection(options: net.NetConnectOpts, cb?: Function): net.Socket;
+    createSocket(req: http.IncomingMessage, options: http.RequestOptions, cb: Function): void;
+    getCurrentStatus(): AgentStatus;
+  }
+
+  export const constants: Constants;
+}
+
+export = AgentKeepAlive;
Index: node_modules/agentkeepalive/index.js
===================================================================
--- node_modules/agentkeepalive/index.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/index.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,7 @@
+'use strict';
+
+const HttpAgent = require('./lib/agent');
+module.exports = HttpAgent;
+module.exports.HttpAgent = HttpAgent;
+module.exports.HttpsAgent = require('./lib/https_agent');
+module.exports.constants = require('./lib/constants');
Index: node_modules/agentkeepalive/lib/agent.js
===================================================================
--- node_modules/agentkeepalive/lib/agent.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/lib/agent.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,402 @@
+'use strict';
+
+const OriginalAgent = require('http').Agent;
+const ms = require('humanize-ms');
+const debug = require('util').debuglog('agentkeepalive');
+const {
+  INIT_SOCKET,
+  CURRENT_ID,
+  CREATE_ID,
+  SOCKET_CREATED_TIME,
+  SOCKET_NAME,
+  SOCKET_REQUEST_COUNT,
+  SOCKET_REQUEST_FINISHED_COUNT,
+} = require('./constants');
+
+// OriginalAgent come from
+// - https://github.com/nodejs/node/blob/v8.12.0/lib/_http_agent.js
+// - https://github.com/nodejs/node/blob/v10.12.0/lib/_http_agent.js
+
+// node <= 10
+let defaultTimeoutListenerCount = 1;
+const majorVersion = parseInt(process.version.split('.', 1)[0].substring(1));
+if (majorVersion >= 11 && majorVersion <= 12) {
+  defaultTimeoutListenerCount = 2;
+} else if (majorVersion >= 13) {
+  defaultTimeoutListenerCount = 3;
+}
+
+function deprecate(message) {
+  console.log('[agentkeepalive:deprecated] %s', message);
+}
+
+class Agent extends OriginalAgent {
+  constructor(options) {
+    options = options || {};
+    options.keepAlive = options.keepAlive !== false;
+    // default is keep-alive and 4s free socket timeout
+    // see https://medium.com/ssense-tech/reduce-networking-errors-in-nodejs-23b4eb9f2d83
+    if (options.freeSocketTimeout === undefined) {
+      options.freeSocketTimeout = 4000;
+    }
+    // Legacy API: keepAliveTimeout should be rename to `freeSocketTimeout`
+    if (options.keepAliveTimeout) {
+      deprecate('options.keepAliveTimeout is deprecated, please use options.freeSocketTimeout instead');
+      options.freeSocketTimeout = options.keepAliveTimeout;
+      delete options.keepAliveTimeout;
+    }
+    // Legacy API: freeSocketKeepAliveTimeout should be rename to `freeSocketTimeout`
+    if (options.freeSocketKeepAliveTimeout) {
+      deprecate('options.freeSocketKeepAliveTimeout is deprecated, please use options.freeSocketTimeout instead');
+      options.freeSocketTimeout = options.freeSocketKeepAliveTimeout;
+      delete options.freeSocketKeepAliveTimeout;
+    }
+
+    // Sets the socket to timeout after timeout milliseconds of inactivity on the socket.
+    // By default is double free socket timeout.
+    if (options.timeout === undefined) {
+      // make sure socket default inactivity timeout >= 8s
+      options.timeout = Math.max(options.freeSocketTimeout * 2, 8000);
+    }
+
+    // support humanize format
+    options.timeout = ms(options.timeout);
+    options.freeSocketTimeout = ms(options.freeSocketTimeout);
+    options.socketActiveTTL = options.socketActiveTTL ? ms(options.socketActiveTTL) : 0;
+
+    super(options);
+
+    this[CURRENT_ID] = 0;
+
+    // create socket success counter
+    this.createSocketCount = 0;
+    this.createSocketCountLastCheck = 0;
+
+    this.createSocketErrorCount = 0;
+    this.createSocketErrorCountLastCheck = 0;
+
+    this.closeSocketCount = 0;
+    this.closeSocketCountLastCheck = 0;
+
+    // socket error event count
+    this.errorSocketCount = 0;
+    this.errorSocketCountLastCheck = 0;
+
+    // request finished counter
+    this.requestCount = 0;
+    this.requestCountLastCheck = 0;
+
+    // including free socket timeout counter
+    this.timeoutSocketCount = 0;
+    this.timeoutSocketCountLastCheck = 0;
+
+    this.on('free', socket => {
+      // https://github.com/nodejs/node/pull/32000
+      // Node.js native agent will check socket timeout eqs agent.options.timeout.
+      // Use the ttl or freeSocketTimeout to overwrite.
+      const timeout = this.calcSocketTimeout(socket);
+      if (timeout > 0 && socket.timeout !== timeout) {
+        socket.setTimeout(timeout);
+      }
+    });
+  }
+
+  get freeSocketKeepAliveTimeout() {
+    deprecate('agent.freeSocketKeepAliveTimeout is deprecated, please use agent.options.freeSocketTimeout instead');
+    return this.options.freeSocketTimeout;
+  }
+
+  get timeout() {
+    deprecate('agent.timeout is deprecated, please use agent.options.timeout instead');
+    return this.options.timeout;
+  }
+
+  get socketActiveTTL() {
+    deprecate('agent.socketActiveTTL is deprecated, please use agent.options.socketActiveTTL instead');
+    return this.options.socketActiveTTL;
+  }
+
+  calcSocketTimeout(socket) {
+    /**
+     * return <= 0: should free socket
+     * return > 0: should update socket timeout
+     * return undefined: not find custom timeout
+     */
+    let freeSocketTimeout = this.options.freeSocketTimeout;
+    const socketActiveTTL = this.options.socketActiveTTL;
+    if (socketActiveTTL) {
+      // check socketActiveTTL
+      const aliveTime = Date.now() - socket[SOCKET_CREATED_TIME];
+      const diff = socketActiveTTL - aliveTime;
+      if (diff <= 0) {
+        return diff;
+      }
+      if (freeSocketTimeout && diff < freeSocketTimeout) {
+        freeSocketTimeout = diff;
+      }
+    }
+    // set freeSocketTimeout
+    if (freeSocketTimeout) {
+      // set free keepalive timer
+      // try to use socket custom freeSocketTimeout first, support headers['keep-alive']
+      // https://github.com/node-modules/urllib/blob/b76053020923f4d99a1c93cf2e16e0c5ba10bacf/lib/urllib.js#L498
+      const customFreeSocketTimeout = socket.freeSocketTimeout || socket.freeSocketKeepAliveTimeout;
+      return customFreeSocketTimeout || freeSocketTimeout;
+    }
+  }
+
+  keepSocketAlive(socket) {
+    const result = super.keepSocketAlive(socket);
+    // should not keepAlive, do nothing
+    if (!result) return result;
+
+    const customTimeout = this.calcSocketTimeout(socket);
+    if (typeof customTimeout === 'undefined') {
+      return true;
+    }
+    if (customTimeout <= 0) {
+      debug('%s(requests: %s, finished: %s) free but need to destroy by TTL, request count %s, diff is %s',
+        socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], customTimeout);
+      return false;
+    }
+    if (socket.timeout !== customTimeout) {
+      socket.setTimeout(customTimeout);
+    }
+    return true;
+  }
+
+  // only call on addRequest
+  reuseSocket(...args) {
+    // reuseSocket(socket, req)
+    super.reuseSocket(...args);
+    const socket = args[0];
+    const req = args[1];
+    req.reusedSocket = true;
+    const agentTimeout = this.options.timeout;
+    if (getSocketTimeout(socket) !== agentTimeout) {
+      // reset timeout before use
+      socket.setTimeout(agentTimeout);
+      debug('%s reset timeout to %sms', socket[SOCKET_NAME], agentTimeout);
+    }
+    socket[SOCKET_REQUEST_COUNT]++;
+    debug('%s(requests: %s, finished: %s) reuse on addRequest, timeout %sms',
+      socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT],
+      getSocketTimeout(socket));
+  }
+
+  [CREATE_ID]() {
+    const id = this[CURRENT_ID]++;
+    if (this[CURRENT_ID] === Number.MAX_SAFE_INTEGER) this[CURRENT_ID] = 0;
+    return id;
+  }
+
+  [INIT_SOCKET](socket, options) {
+    // bugfix here.
+    // https on node 8, 10 won't set agent.options.timeout by default
+    // TODO: need to fix on node itself
+    if (options.timeout) {
+      const timeout = getSocketTimeout(socket);
+      if (!timeout) {
+        socket.setTimeout(options.timeout);
+      }
+    }
+
+    if (this.options.keepAlive) {
+      // Disable Nagle's algorithm: http://blog.caustik.com/2012/04/08/scaling-node-js-to-100k-concurrent-connections/
+      // https://fengmk2.com/benchmark/nagle-algorithm-delayed-ack-mock.html
+      socket.setNoDelay(true);
+    }
+    this.createSocketCount++;
+    if (this.options.socketActiveTTL) {
+      socket[SOCKET_CREATED_TIME] = Date.now();
+    }
+    // don't show the hole '-----BEGIN CERTIFICATE----' key string
+    socket[SOCKET_NAME] = `sock[${this[CREATE_ID]()}#${options._agentKey}]`.split('-----BEGIN', 1)[0];
+    socket[SOCKET_REQUEST_COUNT] = 1;
+    socket[SOCKET_REQUEST_FINISHED_COUNT] = 0;
+    installListeners(this, socket, options);
+  }
+
+  createConnection(options, oncreate) {
+    let called = false;
+    const onNewCreate = (err, socket) => {
+      if (called) return;
+      called = true;
+
+      if (err) {
+        this.createSocketErrorCount++;
+        return oncreate(err);
+      }
+      this[INIT_SOCKET](socket, options);
+      oncreate(err, socket);
+    };
+
+    const newSocket = super.createConnection(options, onNewCreate);
+    if (newSocket) onNewCreate(null, newSocket);
+    return newSocket;
+  }
+
+  get statusChanged() {
+    const changed = this.createSocketCount !== this.createSocketCountLastCheck ||
+      this.createSocketErrorCount !== this.createSocketErrorCountLastCheck ||
+      this.closeSocketCount !== this.closeSocketCountLastCheck ||
+      this.errorSocketCount !== this.errorSocketCountLastCheck ||
+      this.timeoutSocketCount !== this.timeoutSocketCountLastCheck ||
+      this.requestCount !== this.requestCountLastCheck;
+    if (changed) {
+      this.createSocketCountLastCheck = this.createSocketCount;
+      this.createSocketErrorCountLastCheck = this.createSocketErrorCount;
+      this.closeSocketCountLastCheck = this.closeSocketCount;
+      this.errorSocketCountLastCheck = this.errorSocketCount;
+      this.timeoutSocketCountLastCheck = this.timeoutSocketCount;
+      this.requestCountLastCheck = this.requestCount;
+    }
+    return changed;
+  }
+
+  getCurrentStatus() {
+    return {
+      createSocketCount: this.createSocketCount,
+      createSocketErrorCount: this.createSocketErrorCount,
+      closeSocketCount: this.closeSocketCount,
+      errorSocketCount: this.errorSocketCount,
+      timeoutSocketCount: this.timeoutSocketCount,
+      requestCount: this.requestCount,
+      freeSockets: inspect(this.freeSockets),
+      sockets: inspect(this.sockets),
+      requests: inspect(this.requests),
+    };
+  }
+}
+
+// node 8 don't has timeout attribute on socket
+// https://github.com/nodejs/node/pull/21204/files#diff-e6ef024c3775d787c38487a6309e491dR408
+function getSocketTimeout(socket) {
+  return socket.timeout || socket._idleTimeout;
+}
+
+function installListeners(agent, socket, options) {
+  debug('%s create, timeout %sms', socket[SOCKET_NAME], getSocketTimeout(socket));
+
+  // listener socket events: close, timeout, error, free
+  function onFree() {
+    // create and socket.emit('free') logic
+    // https://github.com/nodejs/node/blob/master/lib/_http_agent.js#L311
+    // no req on the socket, it should be the new socket
+    if (!socket._httpMessage && socket[SOCKET_REQUEST_COUNT] === 1) return;
+
+    socket[SOCKET_REQUEST_FINISHED_COUNT]++;
+    agent.requestCount++;
+    debug('%s(requests: %s, finished: %s) free',
+      socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT]);
+
+    // should reuse on pedding requests?
+    const name = agent.getName(options);
+    if (socket.writable && agent.requests[name] && agent.requests[name].length) {
+      // will be reuse on agent free listener
+      socket[SOCKET_REQUEST_COUNT]++;
+      debug('%s(requests: %s, finished: %s) will be reuse on agent free event',
+        socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT]);
+    }
+  }
+  socket.on('free', onFree);
+
+  function onClose(isError) {
+    debug('%s(requests: %s, finished: %s) close, isError: %s',
+      socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT], isError);
+    agent.closeSocketCount++;
+  }
+  socket.on('close', onClose);
+
+  // start socket timeout handler
+  function onTimeout() {
+    // onTimeout and emitRequestTimeout(_http_client.js)
+    // https://github.com/nodejs/node/blob/v12.x/lib/_http_client.js#L711
+    const listenerCount = socket.listeners('timeout').length;
+    // node <= 10, default listenerCount is 1, onTimeout
+    // 11 < node <= 12, default listenerCount is 2, onTimeout and emitRequestTimeout
+    // node >= 13, default listenerCount is 3, onTimeout,
+    //   onTimeout(https://github.com/nodejs/node/pull/32000/files#diff-5f7fb0850412c6be189faeddea6c5359R333)
+    //   and emitRequestTimeout
+    const timeout = getSocketTimeout(socket);
+    const req = socket._httpMessage;
+    const reqTimeoutListenerCount = req && req.listeners('timeout').length || 0;
+    debug('%s(requests: %s, finished: %s) timeout after %sms, listeners %s, defaultTimeoutListenerCount %s, hasHttpRequest %s, HttpRequest timeoutListenerCount %s',
+      socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT],
+      timeout, listenerCount, defaultTimeoutListenerCount, !!req, reqTimeoutListenerCount);
+    if (debug.enabled) {
+      debug('timeout listeners: %s', socket.listeners('timeout').map(f => f.name).join(', '));
+    }
+    agent.timeoutSocketCount++;
+    const name = agent.getName(options);
+    if (agent.freeSockets[name] && agent.freeSockets[name].indexOf(socket) !== -1) {
+      // free socket timeout, destroy quietly
+      socket.destroy();
+      // Remove it from freeSockets list immediately to prevent new requests
+      // from being sent through this socket.
+      agent.removeSocket(socket, options);
+      debug('%s is free, destroy quietly', socket[SOCKET_NAME]);
+    } else {
+      // if there is no any request socket timeout handler,
+      // agent need to handle socket timeout itself.
+      //
+      // custom request socket timeout handle logic must follow these rules:
+      //  1. Destroy socket first
+      //  2. Must emit socket 'agentRemove' event tell agent remove socket
+      //     from freeSockets list immediately.
+      //     Otherise you may be get 'socket hang up' error when reuse
+      //     free socket and timeout happen in the same time.
+      if (reqTimeoutListenerCount === 0) {
+        const error = new Error('Socket timeout');
+        error.code = 'ERR_SOCKET_TIMEOUT';
+        error.timeout = timeout;
+        // must manually call socket.end() or socket.destroy() to end the connection.
+        // https://nodejs.org/dist/latest-v10.x/docs/api/net.html#net_socket_settimeout_timeout_callback
+        socket.destroy(error);
+        agent.removeSocket(socket, options);
+        debug('%s destroy with timeout error', socket[SOCKET_NAME]);
+      }
+    }
+  }
+  socket.on('timeout', onTimeout);
+
+  function onError(err) {
+    const listenerCount = socket.listeners('error').length;
+    debug('%s(requests: %s, finished: %s) error: %s, listenerCount: %s',
+      socket[SOCKET_NAME], socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT],
+      err, listenerCount);
+    agent.errorSocketCount++;
+    if (listenerCount === 1) {
+      // if socket don't contain error event handler, don't catch it, emit it again
+      debug('%s emit uncaught error event', socket[SOCKET_NAME]);
+      socket.removeListener('error', onError);
+      socket.emit('error', err);
+    }
+  }
+  socket.on('error', onError);
+
+  function onRemove() {
+    debug('%s(requests: %s, finished: %s) agentRemove',
+      socket[SOCKET_NAME],
+      socket[SOCKET_REQUEST_COUNT], socket[SOCKET_REQUEST_FINISHED_COUNT]);
+    // We need this function for cases like HTTP 'upgrade'
+    // (defined by WebSockets) where we need to remove a socket from the
+    // pool because it'll be locked up indefinitely
+    socket.removeListener('close', onClose);
+    socket.removeListener('error', onError);
+    socket.removeListener('free', onFree);
+    socket.removeListener('timeout', onTimeout);
+    socket.removeListener('agentRemove', onRemove);
+  }
+  socket.on('agentRemove', onRemove);
+}
+
+module.exports = Agent;
+
+function inspect(obj) {
+  const res = {};
+  for (const key in obj) {
+    res[key] = obj[key].length;
+  }
+  return res;
+}
Index: node_modules/agentkeepalive/lib/constants.js
===================================================================
--- node_modules/agentkeepalive/lib/constants.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/lib/constants.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,14 @@
+'use strict';
+
+module.exports = {
+  // agent
+  CURRENT_ID: Symbol('agentkeepalive#currentId'),
+  CREATE_ID: Symbol('agentkeepalive#createId'),
+  INIT_SOCKET: Symbol('agentkeepalive#initSocket'),
+  CREATE_HTTPS_CONNECTION: Symbol('agentkeepalive#createHttpsConnection'),
+  // socket
+  SOCKET_CREATED_TIME: Symbol('agentkeepalive#socketCreatedTime'),
+  SOCKET_NAME: Symbol('agentkeepalive#socketName'),
+  SOCKET_REQUEST_COUNT: Symbol('agentkeepalive#socketRequestCount'),
+  SOCKET_REQUEST_FINISHED_COUNT: Symbol('agentkeepalive#socketRequestFinishedCount'),
+};
Index: node_modules/agentkeepalive/lib/https_agent.js
===================================================================
--- node_modules/agentkeepalive/lib/https_agent.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/lib/https_agent.js	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,51 @@
+'use strict';
+
+const OriginalHttpsAgent = require('https').Agent;
+const HttpAgent = require('./agent');
+const {
+  INIT_SOCKET,
+  CREATE_HTTPS_CONNECTION,
+} = require('./constants');
+
+class HttpsAgent extends HttpAgent {
+  constructor(options) {
+    super(options);
+
+    this.defaultPort = 443;
+    this.protocol = 'https:';
+    this.maxCachedSessions = this.options.maxCachedSessions;
+    /* istanbul ignore next */
+    if (this.maxCachedSessions === undefined) {
+      this.maxCachedSessions = 100;
+    }
+
+    this._sessionCache = {
+      map: {},
+      list: [],
+    };
+  }
+
+  createConnection(options, oncreate) {
+    const socket = this[CREATE_HTTPS_CONNECTION](options, oncreate);
+    this[INIT_SOCKET](socket, options);
+    return socket;
+  }
+}
+
+// https://github.com/nodejs/node/blob/master/lib/https.js#L89
+HttpsAgent.prototype[CREATE_HTTPS_CONNECTION] = OriginalHttpsAgent.prototype.createConnection;
+
+[
+  'getName',
+  '_getSession',
+  '_cacheSession',
+  // https://github.com/nodejs/node/pull/4982
+  '_evictSession',
+].forEach(function(method) {
+  /* istanbul ignore next */
+  if (typeof OriginalHttpsAgent.prototype[method] === 'function') {
+    HttpsAgent.prototype[method] = OriginalHttpsAgent.prototype[method];
+  }
+});
+
+module.exports = HttpsAgent;
Index: node_modules/agentkeepalive/package.json
===================================================================
--- node_modules/agentkeepalive/package.json	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
+++ node_modules/agentkeepalive/package.json	(revision 81bc7da776d8cda42939ef4ab350c88d13b4941f)
@@ -0,0 +1,56 @@
+{
+  "name": "agentkeepalive",
+  "version": "4.6.0",
+  "description": "Missing keepalive http.Agent",
+  "main": "index.js",
+  "browser": "browser.js",
+  "files": [
+    "index.js",
+    "index.d.ts",
+    "browser.js",
+    "lib"
+  ],
+  "scripts": {
+    "contributor": "git-contributor",
+    "test": "npm run lint && egg-bin test --full-trace",
+    "test-local": "egg-bin test --full-trace",
+    "cov": "cross-env NODE_DEBUG=agentkeepalive egg-bin cov --full-trace",
+    "ci": "npm run lint && npm run cov",
+    "lint": "eslint lib test index.js"
+  },
+  "repository": {
+    "type": "git",
+    "url": "git://github.com/node-modules/agentkeepalive.git"
+  },
+  "bugs": {
+    "url": "https://github.com/node-modules/agentkeepalive/issues"
+  },
+  "keywords": [
+    "http",
+    "https",
+    "agent",
+    "keepalive",
+    "agentkeepalive",
+    "HttpAgent",
+    "HttpsAgent"
+  ],
+  "dependencies": {
+    "humanize-ms": "^1.2.1"
+  },
+  "devDependencies": {
+    "coffee": "^5.3.0",
+    "cross-env": "^6.0.3",
+    "egg-bin": "^4.9.0",
+    "eslint": "^5.7.0",
+    "eslint-config-egg": "^7.1.0",
+    "git-contributor": "^2.0.0",
+    "mm": "^2.4.1",
+    "pedding": "^1.1.0",
+    "typescript": "^3.8.3"
+  },
+  "engines": {
+    "node": ">= 8.0.0"
+  },
+  "author": "fengmk2 <fengmk2@gmail.com> (https://github.com/fengmk2)",
+  "license": "MIT"
+}
