global-agent 4.1.1 → 4.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (76) hide show
  1. package/dist/Logger.d.ts +11 -0
  2. package/dist/Logger.js +56 -0
  3. package/dist/classes/Agent.d.ts +46 -0
  4. package/dist/classes/Agent.js +216 -0
  5. package/dist/classes/HttpProxyAgent.d.ts +7 -0
  6. package/dist/classes/HttpProxyAgent.js +20 -0
  7. package/dist/classes/HttpsProxyAgent.d.ts +7 -0
  8. package/dist/classes/HttpsProxyAgent.js +48 -0
  9. package/dist/classes/index.d.ts +3 -0
  10. package/dist/classes/index.js +12 -0
  11. package/dist/errors.d.ts +4 -0
  12. package/dist/errors.js +10 -0
  13. package/dist/factories/createGlobalProxyAgent.d.ts +7 -0
  14. package/dist/factories/createGlobalProxyAgent.js +131 -0
  15. package/dist/factories/createGlobalProxyAgent.test.d.ts +1 -0
  16. package/dist/factories/createGlobalProxyAgent.test.js +539 -0
  17. package/dist/factories/createProxyController.d.ts +7 -0
  18. package/dist/factories/createProxyController.js +38 -0
  19. package/dist/factories/createProxyController.test.d.ts +1 -0
  20. package/dist/factories/createProxyController.test.js +29 -0
  21. package/dist/factories/index.d.ts +2 -0
  22. package/dist/factories/index.js +10 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.js +7 -0
  25. package/dist/routines/bootstrap.d.ts +3 -0
  26. package/dist/routines/bootstrap.js +20 -0
  27. package/dist/routines/index.d.ts +1 -0
  28. package/dist/routines/index.js +8 -0
  29. package/dist/types.d.ts +57 -0
  30. package/dist/types.js +2 -0
  31. package/dist/utilities/bindHttpMethod.d.ts +7 -0
  32. package/dist/utilities/bindHttpMethod.js +50 -0
  33. package/dist/utilities/index.d.ts +3 -0
  34. package/dist/utilities/index.js +12 -0
  35. package/dist/utilities/isUrlMatchingNoProxy.d.ts +2 -0
  36. package/dist/utilities/isUrlMatchingNoProxy.js +27 -0
  37. package/dist/utilities/isUrlMatchingNoProxy.test.d.ts +1 -0
  38. package/dist/utilities/isUrlMatchingNoProxy.test.js +61 -0
  39. package/dist/utilities/parseBoolean.d.ts +1 -0
  40. package/dist/utilities/parseBoolean.js +16 -0
  41. package/dist/utilities/parseProxyUrl.d.ts +6 -0
  42. package/dist/utilities/parseProxyUrl.js +31 -0
  43. package/dist/utilities/parseProxyUrl.test.d.ts +1 -0
  44. package/dist/utilities/parseProxyUrl.test.js +31 -0
  45. package/package.json +5 -4
  46. package/.babelrc +0 -23
  47. package/.editorconfig +0 -9
  48. package/.github/FUNDING.yml +0 -2
  49. package/.github/workflows/feature.yaml +0 -35
  50. package/.github/workflows/main.yaml +0 -50
  51. package/.gitignore +0 -12
  52. package/bootstrap.js +0 -1
  53. package/src/Logger.ts +0 -70
  54. package/src/classes/Agent.ts +0 -296
  55. package/src/classes/HttpProxyAgent.ts +0 -45
  56. package/src/classes/HttpsProxyAgent.ts +0 -83
  57. package/src/classes/index.ts +0 -9
  58. package/src/errors.ts +0 -11
  59. package/src/factories/createGlobalProxyAgent.test.ts +0 -761
  60. package/src/factories/createGlobalProxyAgent.ts +0 -190
  61. package/src/factories/createProxyController.test.ts +0 -38
  62. package/src/factories/createProxyController.ts +0 -51
  63. package/src/factories/index.ts +0 -6
  64. package/src/index.ts +0 -9
  65. package/src/routines/bootstrap.ts +0 -28
  66. package/src/routines/index.ts +0 -3
  67. package/src/types.ts +0 -70
  68. package/src/utilities/bindHttpMethod.ts +0 -53
  69. package/src/utilities/index.ts +0 -9
  70. package/src/utilities/isUrlMatchingNoProxy.test.ts +0 -77
  71. package/src/utilities/isUrlMatchingNoProxy.ts +0 -32
  72. package/src/utilities/parseBoolean.ts +0 -17
  73. package/src/utilities/parseProxyUrl.test.ts +0 -35
  74. package/src/utilities/parseProxyUrl.ts +0 -39
  75. package/tsconfig.json +0 -25
  76. package/vitest.config.ts +0 -11
@@ -0,0 +1,11 @@
1
+ export type LogMethod = (context: object | string, message?: string) => void;
2
+ export type Logger = {
3
+ child: (context: object) => Logger;
4
+ debug: LogMethod;
5
+ error: LogMethod;
6
+ info: LogMethod;
7
+ trace: LogMethod;
8
+ warn: LogMethod;
9
+ };
10
+ export declare const setLogger: (newLogger: Logger) => void;
11
+ export declare const logger: Logger;
package/dist/Logger.js ADDED
@@ -0,0 +1,56 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.logger = exports.setLogger = void 0;
4
+ // oxlint-disable-next-line @typescript-eslint/no-empty-function
5
+ const noop = () => { };
6
+ const createNoopLogger = () => {
7
+ return {
8
+ child: () => {
9
+ return createNoopLogger();
10
+ },
11
+ debug: noop,
12
+ error: noop,
13
+ info: noop,
14
+ trace: noop,
15
+ warn: noop,
16
+ };
17
+ };
18
+ let currentLogger = createNoopLogger();
19
+ const setLogger = (newLogger) => {
20
+ currentLogger = newLogger;
21
+ };
22
+ exports.setLogger = setLogger;
23
+ const createDelegatingLogger = (getContext) => {
24
+ const getLogger = () => {
25
+ let targetLogger = currentLogger;
26
+ for (const [key, value] of Object.entries(getContext())) {
27
+ targetLogger = targetLogger.child({ [key]: value });
28
+ }
29
+ return targetLogger;
30
+ };
31
+ return {
32
+ child: (context) => {
33
+ return createDelegatingLogger(() => {
34
+ return { ...getContext(), ...context };
35
+ });
36
+ },
37
+ debug: (context, message) => {
38
+ getLogger().debug(context, message);
39
+ },
40
+ error: (context, message) => {
41
+ getLogger().error(context, message);
42
+ },
43
+ info: (context, message) => {
44
+ getLogger().info(context, message);
45
+ },
46
+ trace: (context, message) => {
47
+ getLogger().trace(context, message);
48
+ },
49
+ warn: (context, message) => {
50
+ getLogger().warn(context, message);
51
+ },
52
+ };
53
+ };
54
+ exports.logger = createDelegatingLogger(() => {
55
+ return { package: 'global-agent' };
56
+ });
@@ -0,0 +1,46 @@
1
+ /// <reference types="node" />
2
+ /// <reference types="node" />
3
+ import type * as http from 'http';
4
+ import type * as https from 'https';
5
+ import type { AgentType, ConnectionCallbackType, ConnectionConfigurationType, GetUrlProxyMethodType, IsProxyConfiguredMethodType, MustUrlUseProxyMethodType, ProtocolType } from '../types';
6
+ type AgentRequestOptions = {
7
+ host?: string;
8
+ path?: string;
9
+ port: number;
10
+ };
11
+ type HttpRequestOptions = AgentRequestOptions & Omit<http.RequestOptions, keyof AgentRequestOptions> & {
12
+ secureEndpoint: false;
13
+ };
14
+ type HttpsRequestOptions = AgentRequestOptions & Omit<https.RequestOptions, keyof AgentRequestOptions> & {
15
+ secureEndpoint: true;
16
+ };
17
+ type RequestOptions = HttpRequestOptions | HttpsRequestOptions;
18
+ declare abstract class Agent {
19
+ defaultPort: number;
20
+ protocol: ProtocolType;
21
+ fallbackAgent: AgentType;
22
+ isProxyConfigured: IsProxyConfiguredMethodType;
23
+ mustUrlUseProxy: MustUrlUseProxyMethodType;
24
+ getUrlProxy: GetUrlProxyMethodType;
25
+ socketConnectionTimeout: number;
26
+ ca: string[] | string | undefined;
27
+ constructor(isProxyConfigured: IsProxyConfiguredMethodType, mustUrlUseProxy: MustUrlUseProxyMethodType, getUrlProxy: GetUrlProxyMethodType, fallbackAgent: AgentType, socketConnectionTimeout: number, ca: string[] | string | undefined);
28
+ /**
29
+ * This method can be used to append new ca certificates to existing ca certificates
30
+ *
31
+ * @param {string[] | string} ca a ca certificate or an array of ca certificates
32
+ */
33
+ addCACertificates(ca: string[] | string): void;
34
+ /**
35
+ * This method clears existing CA Certificates.
36
+ * It sets ca to undefined
37
+ */
38
+ clearCACertificates(): void;
39
+ /**
40
+ * Evaluate value for tls reject unauthorized variable
41
+ */
42
+ getRejectUnauthorized(): boolean;
43
+ abstract createConnection(configuration: ConnectionConfigurationType, callback: ConnectionCallbackType): void;
44
+ addRequest(request: http.ClientRequest, configuration: RequestOptions): void;
45
+ }
46
+ export default Agent;
@@ -0,0 +1,216 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const net_1 = __importDefault(require("net"));
7
+ const serialize_error_1 = require("serialize-error");
8
+ const Logger_1 = require("../Logger");
9
+ const log = Logger_1.logger.child({
10
+ namespace: 'Agent',
11
+ });
12
+ let requestId = 0;
13
+ class Agent {
14
+ constructor(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca) {
15
+ this.fallbackAgent = fallbackAgent;
16
+ this.isProxyConfigured = isProxyConfigured;
17
+ this.mustUrlUseProxy = mustUrlUseProxy;
18
+ this.getUrlProxy = getUrlProxy;
19
+ this.socketConnectionTimeout = socketConnectionTimeout;
20
+ this.ca = ca;
21
+ }
22
+ /**
23
+ * This method can be used to append new ca certificates to existing ca certificates
24
+ *
25
+ * @param {string[] | string} ca a ca certificate or an array of ca certificates
26
+ */
27
+ addCACertificates(ca) {
28
+ if (!ca) {
29
+ log.error('Invalid input ca certificate');
30
+ }
31
+ else if (this.ca) {
32
+ if (typeof ca === typeof this.ca) {
33
+ // concat valid ca certificates with the existing certificates,
34
+ if (typeof this.ca === 'string') {
35
+ this.ca = this.ca.concat(ca);
36
+ }
37
+ else {
38
+ this.ca = this.ca.concat(ca);
39
+ }
40
+ }
41
+ else {
42
+ log.error('Input ca certificate type mismatched with existing ca certificate type');
43
+ }
44
+ }
45
+ else {
46
+ this.ca = ca;
47
+ }
48
+ }
49
+ /**
50
+ * This method clears existing CA Certificates.
51
+ * It sets ca to undefined
52
+ */
53
+ clearCACertificates() {
54
+ this.ca = undefined;
55
+ }
56
+ /**
57
+ * Evaluate value for tls reject unauthorized variable
58
+ */
59
+ getRejectUnauthorized() {
60
+ // oxlint-disable-next-line node/no-process-env
61
+ const rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
62
+ let returnValue = true;
63
+ if (typeof rejectUnauthorized === 'boolean') {
64
+ returnValue = rejectUnauthorized;
65
+ }
66
+ else if (typeof rejectUnauthorized === 'number') {
67
+ returnValue = rejectUnauthorized === 1;
68
+ }
69
+ else if (typeof rejectUnauthorized === 'string') {
70
+ returnValue = ['true', 't', 'yes', 'y', 'on', '1'].includes(rejectUnauthorized.trim().toLowerCase());
71
+ }
72
+ return returnValue;
73
+ }
74
+ addRequest(request, configuration) {
75
+ var _a, _b, _c, _d, _e, _f, _g, _h;
76
+ let requestUrl;
77
+ // It is possible that addRequest was constructed for a proxied request already, e.g.
78
+ // "request" package does this when it detects that a proxy should be used
79
+ // https://github.com/request/request/blob/212570b6971a732b8dd9f3c73354bcdda158a737/request.js#L402
80
+ // https://gist.github.com/gajus/e2074cd3b747864ffeaabbd530d30218
81
+ if ((_a = request.path.startsWith('http://')) !== null && _a !== void 0 ? _a : request.path.startsWith('https://')) {
82
+ requestUrl = request.path;
83
+ }
84
+ else if (request.method === 'CONNECT') {
85
+ requestUrl = 'https://' + request.path;
86
+ }
87
+ else {
88
+ requestUrl = this.protocol + '//' + ((_b = configuration.hostname) !== null && _b !== void 0 ? _b : configuration.host) + (configuration.port === 80 || configuration.port === 443 ? '' : ':' + configuration.port) + request.path;
89
+ }
90
+ // If a request should go to a local socket, proxying it through an HTTP
91
+ // server does not make sense as the information about the target socket
92
+ // will be lost and the proxy won't be able to correctly handle the request.
93
+ if (configuration.socketPath) {
94
+ log.trace({
95
+ destination: configuration.socketPath,
96
+ }, 'not proxying request; destination is a socket');
97
+ // @ts-expect-error seems like we are using wrong type for fallbackAgent.
98
+ this.fallbackAgent.addRequest(request, configuration);
99
+ return;
100
+ }
101
+ if (!this.isProxyConfigured()) {
102
+ log.trace({
103
+ destination: requestUrl,
104
+ }, 'not proxying request; GLOBAL_AGENT.HTTP_PROXY is not configured');
105
+ // @ts-expect-error seems like we are using wrong type for fallbackAgent.
106
+ this.fallbackAgent.addRequest(request, configuration);
107
+ return;
108
+ }
109
+ if (!this.mustUrlUseProxy(requestUrl)) {
110
+ log.trace({
111
+ destination: requestUrl,
112
+ }, 'not proxying request; url matches GLOBAL_AGENT.NO_PROXY');
113
+ // @ts-expect-error seems like we are using wrong type for fallbackAgent.
114
+ this.fallbackAgent.addRequest(request, configuration);
115
+ return;
116
+ }
117
+ const currentRequestId = requestId++;
118
+ const proxy = this.getUrlProxy(requestUrl);
119
+ if (this.protocol === 'http:') {
120
+ request.path = requestUrl;
121
+ if (proxy.authorization) {
122
+ request.setHeader('proxy-authorization', 'Basic ' + Buffer.from(proxy.authorization).toString('base64'));
123
+ }
124
+ }
125
+ log.trace({
126
+ destination: requestUrl,
127
+ proxy: 'http://' + proxy.hostname + ':' + proxy.port,
128
+ requestId: currentRequestId,
129
+ }, 'proxying request');
130
+ request.on('error', (error) => {
131
+ log.error({
132
+ error: (0, serialize_error_1.serializeError)(error),
133
+ }, 'request error');
134
+ });
135
+ request.once('response', (response) => {
136
+ log.trace({
137
+ headers: response.headers,
138
+ requestId: currentRequestId,
139
+ statusCode: response.statusCode,
140
+ }, 'proxying response');
141
+ });
142
+ request.shouldKeepAlive = false;
143
+ const connectionConfiguration = {
144
+ host: (_d = (_c = configuration.hostname) !== null && _c !== void 0 ? _c : configuration.host) !== null && _d !== void 0 ? _d : '',
145
+ port: (_e = configuration.port) !== null && _e !== void 0 ? _e : 80,
146
+ proxy,
147
+ tls: {},
148
+ };
149
+ // add optional tls options for https requests.
150
+ // @see https://nodejs.org/docs/latest-v12.x/api/https.html#https_https_request_url_options_callback :
151
+ // > The following additional options from tls.connect()
152
+ // > - https://nodejs.org/docs/latest-v12.x/api/tls.html#tls_tls_connect_options_callback -
153
+ // > are also accepted:
154
+ // > ca, cert, ciphers, clientCertEngine, crl, dhparam, ecdhCurve, honorCipherOrder,
155
+ // > key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext.
156
+ if (configuration.secureEndpoint) {
157
+ // Determine servername - Node.js doesn't allow IP addresses as servername
158
+ const host = (_f = configuration.servername) !== null && _f !== void 0 ? _f : connectionConfiguration.host;
159
+ const servername = net_1.default.isIP(host) ? undefined : host;
160
+ connectionConfiguration.tls = {
161
+ ca: (_g = configuration.ca) !== null && _g !== void 0 ? _g : this.ca,
162
+ cert: configuration.cert,
163
+ ciphers: configuration.ciphers,
164
+ clientCertEngine: configuration.clientCertEngine,
165
+ crl: configuration.crl,
166
+ dhparam: configuration.dhparam,
167
+ ecdhCurve: configuration.ecdhCurve,
168
+ honorCipherOrder: configuration.honorCipherOrder,
169
+ key: configuration.key,
170
+ passphrase: configuration.passphrase,
171
+ pfx: configuration.pfx,
172
+ rejectUnauthorized: (_h = configuration.rejectUnauthorized) !== null && _h !== void 0 ? _h : this.getRejectUnauthorized(),
173
+ secureOptions: configuration.secureOptions,
174
+ secureProtocol: configuration.secureProtocol,
175
+ servername,
176
+ sessionIdContext: configuration.sessionIdContext,
177
+ };
178
+ }
179
+ this.createConnection(connectionConfiguration, (error, socket) => {
180
+ log.trace({
181
+ target: connectionConfiguration,
182
+ }, 'connecting');
183
+ // @see https://github.com/nodejs/node/issues/5757#issuecomment-305969057
184
+ if (socket) {
185
+ socket.setTimeout(this.socketConnectionTimeout, () => {
186
+ socket.destroy();
187
+ });
188
+ socket.once('connect', () => {
189
+ log.trace({
190
+ target: connectionConfiguration,
191
+ }, 'connected');
192
+ socket.setTimeout(0);
193
+ });
194
+ socket.once('secureConnect', () => {
195
+ log.trace({
196
+ target: connectionConfiguration,
197
+ }, 'connected (secure)');
198
+ socket.setTimeout(0);
199
+ });
200
+ }
201
+ if (error) {
202
+ request.emit('error', error);
203
+ }
204
+ else if (socket) {
205
+ log.debug('created socket');
206
+ socket.on('error', (socketError) => {
207
+ log.error({
208
+ error: (0, serialize_error_1.serializeError)(socketError),
209
+ }, 'socket error');
210
+ });
211
+ request.onSocket(socket);
212
+ }
213
+ });
214
+ }
215
+ }
216
+ exports.default = Agent;
@@ -0,0 +1,7 @@
1
+ import type { AgentType, ConnectionCallbackType, ConnectionConfigurationType, GetUrlProxyMethodType, IsProxyConfiguredMethodType, MustUrlUseProxyMethodType } from '../types';
2
+ import Agent from './Agent';
3
+ declare class HttpProxyAgent extends Agent {
4
+ constructor(isProxyConfigured: IsProxyConfiguredMethodType, mustUrlUseProxy: MustUrlUseProxyMethodType, getUrlProxy: GetUrlProxyMethodType, fallbackAgent: AgentType, socketConnectionTimeout: number, ca: string[] | string | undefined);
5
+ createConnection(configuration: ConnectionConfigurationType, callback: ConnectionCallbackType): void;
6
+ }
7
+ export default HttpProxyAgent;
@@ -0,0 +1,20 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const net_1 = __importDefault(require("net"));
7
+ const Agent_1 = __importDefault(require("./Agent"));
8
+ class HttpProxyAgent extends Agent_1.default {
9
+ // @see https://github.com/sindresorhus/eslint-plugin-unicorn/issues/169#issuecomment-486980290
10
+ constructor(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca) {
11
+ super(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca);
12
+ this.protocol = 'http:';
13
+ this.defaultPort = 80;
14
+ }
15
+ createConnection(configuration, callback) {
16
+ const socket = net_1.default.connect(configuration.proxy.port, configuration.proxy.hostname);
17
+ callback(null, socket);
18
+ }
19
+ }
20
+ exports.default = HttpProxyAgent;
@@ -0,0 +1,7 @@
1
+ import type { AgentType, ConnectionCallbackType, ConnectionConfigurationType, GetUrlProxyMethodType, IsProxyConfiguredMethodType, MustUrlUseProxyMethodType } from '../types';
2
+ import Agent from './Agent';
3
+ declare class HttpsProxyAgent extends Agent {
4
+ constructor(isProxyConfigured: IsProxyConfiguredMethodType, mustUrlUseProxy: MustUrlUseProxyMethodType, getUrlProxy: GetUrlProxyMethodType, fallbackAgent: AgentType, socketConnectionTimeout: number, ca: string[] | string | undefined);
5
+ createConnection(configuration: ConnectionConfigurationType, callback: ConnectionCallbackType): void;
6
+ }
7
+ export default HttpsProxyAgent;
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const net_1 = __importDefault(require("net"));
7
+ const tls_1 = __importDefault(require("tls"));
8
+ const Agent_1 = __importDefault(require("./Agent"));
9
+ class HttpsProxyAgent extends Agent_1.default {
10
+ constructor(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca) {
11
+ super(isProxyConfigured, mustUrlUseProxy, getUrlProxy, fallbackAgent, socketConnectionTimeout, ca);
12
+ this.protocol = 'https:';
13
+ this.defaultPort = 443;
14
+ }
15
+ createConnection(configuration, callback) {
16
+ const socket = net_1.default.connect(configuration.proxy.port, configuration.proxy.hostname);
17
+ socket.on('error', (error) => {
18
+ callback(error);
19
+ });
20
+ socket.once('data', (data) => {
21
+ var _a;
22
+ // Proxies with HTTPS as protocal are not allowed by parseProxyUrl(), so it should be safe to assume that the response is plain text
23
+ const statusLine = data.toString().split('\r\n')[0];
24
+ const statusLineExp = /^HTTP\/(\d)\.(\d) (\d{3}) ?(.*)$/;
25
+ const statusCode = (_a = statusLineExp.exec(statusLine)) === null || _a === void 0 ? void 0 : _a[3];
26
+ if (typeof statusCode === 'string' && Number(statusCode) >= 400) {
27
+ const error = new Error(`Proxy server refused connecting to '${configuration.host}:${configuration.port}' (${statusLine})`);
28
+ socket.destroy();
29
+ callback(error);
30
+ return;
31
+ }
32
+ const secureSocket = tls_1.default.connect({
33
+ ...configuration.tls,
34
+ socket,
35
+ });
36
+ callback(null, secureSocket);
37
+ });
38
+ let connectMessage = '';
39
+ connectMessage += 'CONNECT ' + configuration.host + ':' + configuration.port + ' HTTP/1.1\r\n';
40
+ connectMessage += 'Host: ' + configuration.host + ':' + configuration.port + '\r\n';
41
+ if (configuration.proxy.authorization) {
42
+ connectMessage += 'Proxy-Authorization: Basic ' + Buffer.from(configuration.proxy.authorization).toString('base64') + '\r\n';
43
+ }
44
+ connectMessage += '\r\n';
45
+ socket.write(connectMessage);
46
+ }
47
+ }
48
+ exports.default = HttpsProxyAgent;
@@ -0,0 +1,3 @@
1
+ export { default as Agent, } from './Agent';
2
+ export { default as HttpProxyAgent, } from './HttpProxyAgent';
3
+ export { default as HttpsProxyAgent, } from './HttpsProxyAgent';
@@ -0,0 +1,12 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HttpsProxyAgent = exports.HttpProxyAgent = exports.Agent = void 0;
7
+ var Agent_1 = require("./Agent");
8
+ Object.defineProperty(exports, "Agent", { enumerable: true, get: function () { return __importDefault(Agent_1).default; } });
9
+ var HttpProxyAgent_1 = require("./HttpProxyAgent");
10
+ Object.defineProperty(exports, "HttpProxyAgent", { enumerable: true, get: function () { return __importDefault(HttpProxyAgent_1).default; } });
11
+ var HttpsProxyAgent_1 = require("./HttpsProxyAgent");
12
+ Object.defineProperty(exports, "HttpsProxyAgent", { enumerable: true, get: function () { return __importDefault(HttpsProxyAgent_1).default; } });
@@ -0,0 +1,4 @@
1
+ export declare class UnexpectedStateError extends Error {
2
+ code: string;
3
+ constructor(message: string, code?: string);
4
+ }
package/dist/errors.js ADDED
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.UnexpectedStateError = void 0;
4
+ class UnexpectedStateError extends Error {
5
+ constructor(message, code = 'UNEXPECTED_STATE_ERROR') {
6
+ super(message);
7
+ this.code = code;
8
+ }
9
+ }
10
+ exports.UnexpectedStateError = UnexpectedStateError;
@@ -0,0 +1,7 @@
1
+ import type { ProxyAgentConfigurationInputType } from '../types';
2
+ declare const _default: (configurationInput?: ProxyAgentConfigurationInputType) => {
3
+ HTTP_PROXY: string | null;
4
+ HTTPS_PROXY: string | null;
5
+ NO_PROXY: string | null;
6
+ };
7
+ export default _default;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ const http_1 = __importDefault(require("http"));
7
+ const https_1 = __importDefault(require("https"));
8
+ const gte_1 = __importDefault(require("semver/functions/gte"));
9
+ const Logger_1 = require("../Logger");
10
+ const classes_1 = require("../classes");
11
+ const errors_1 = require("../errors");
12
+ const utilities_1 = require("../utilities");
13
+ const parseBoolean_1 = require("../utilities/parseBoolean");
14
+ const createProxyController_1 = __importDefault(require("./createProxyController"));
15
+ const httpGet = http_1.default.get;
16
+ const httpRequest = http_1.default.request;
17
+ const httpsGet = https_1.default.get;
18
+ const httpsRequest = https_1.default.request;
19
+ const log = Logger_1.logger.child({
20
+ namespace: 'createGlobalProxyAgent',
21
+ });
22
+ const defaultConfigurationInput = {
23
+ environmentVariableNamespace: undefined,
24
+ forceGlobalAgent: undefined,
25
+ socketConnectionTimeout: 60000,
26
+ };
27
+ const createConfiguration = (configurationInput) => {
28
+ // oxlint-disable-next-line node/no-process-env
29
+ const environment = process.env;
30
+ const defaultConfiguration = {
31
+ environmentVariableNamespace: typeof environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE === 'string' ? environment.GLOBAL_AGENT_ENVIRONMENT_VARIABLE_NAMESPACE : 'GLOBAL_AGENT_',
32
+ forceGlobalAgent: typeof environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT === 'string' ? (0, parseBoolean_1.parseBoolean)(environment.GLOBAL_AGENT_FORCE_GLOBAL_AGENT) : true,
33
+ socketConnectionTimeout: typeof environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT === 'string' ? Number.parseInt(environment.GLOBAL_AGENT_SOCKET_CONNECTION_TIMEOUT, 10) : defaultConfigurationInput.socketConnectionTimeout,
34
+ };
35
+ return {
36
+ ...defaultConfiguration,
37
+ ...Object.fromEntries(Object.entries(configurationInput).filter(([, v]) => v !== undefined)),
38
+ };
39
+ };
40
+ exports.default = (configurationInput = defaultConfigurationInput) => {
41
+ var _a, _b, _c;
42
+ const configuration = createConfiguration(configurationInput);
43
+ if (configurationInput.logger) {
44
+ (0, Logger_1.setLogger)(configurationInput.logger);
45
+ }
46
+ const proxyController = (0, createProxyController_1.default)();
47
+ // oxlint-disable-next-line node/no-process-env
48
+ proxyController.HTTP_PROXY = (_a = process.env[configuration.environmentVariableNamespace + 'HTTP_PROXY']) !== null && _a !== void 0 ? _a : null;
49
+ // oxlint-disable-next-line node/no-process-env
50
+ proxyController.HTTPS_PROXY = (_b = process.env[configuration.environmentVariableNamespace + 'HTTPS_PROXY']) !== null && _b !== void 0 ? _b : null;
51
+ // oxlint-disable-next-line node/no-process-env
52
+ proxyController.NO_PROXY = (_c = process.env[configuration.environmentVariableNamespace + 'NO_PROXY']) !== null && _c !== void 0 ? _c : null;
53
+ log.info({
54
+ configuration,
55
+ state: proxyController,
56
+ }, 'global agent has been initialized');
57
+ const mustUrlUseProxy = (getProxy) => {
58
+ return (url) => {
59
+ if (!getProxy()) {
60
+ return false;
61
+ }
62
+ if (!proxyController.NO_PROXY) {
63
+ return true;
64
+ }
65
+ return !(0, utilities_1.isUrlMatchingNoProxy)(url, proxyController.NO_PROXY);
66
+ };
67
+ };
68
+ const getUrlProxy = (getProxy) => {
69
+ return () => {
70
+ const proxy = getProxy();
71
+ if (!proxy) {
72
+ throw new errors_1.UnexpectedStateError('HTTP(S) proxy must be configured.');
73
+ }
74
+ return (0, utilities_1.parseProxyUrl)(proxy);
75
+ };
76
+ };
77
+ const getHttpProxy = () => {
78
+ return proxyController.HTTP_PROXY;
79
+ };
80
+ const BoundHttpProxyAgent = class extends classes_1.HttpProxyAgent {
81
+ constructor() {
82
+ super(() => {
83
+ return Boolean(getHttpProxy());
84
+ }, mustUrlUseProxy(getHttpProxy), getUrlProxy(getHttpProxy), http_1.default.globalAgent, configuration.socketConnectionTimeout, configuration.ca);
85
+ }
86
+ };
87
+ const httpAgent = new BoundHttpProxyAgent();
88
+ const getHttpsProxy = () => {
89
+ var _a;
90
+ return (_a = proxyController.HTTPS_PROXY) !== null && _a !== void 0 ? _a : proxyController.HTTP_PROXY;
91
+ };
92
+ const BoundHttpsProxyAgent = class extends classes_1.HttpsProxyAgent {
93
+ constructor() {
94
+ super(() => {
95
+ return Boolean(getHttpsProxy());
96
+ }, mustUrlUseProxy(getHttpsProxy), getUrlProxy(getHttpsProxy), https_1.default.globalAgent, configuration.socketConnectionTimeout, configuration.ca);
97
+ }
98
+ };
99
+ const httpsAgent = new BoundHttpsProxyAgent();
100
+ // Overriding globalAgent was added in v11.7.
101
+ // @see https://nodejs.org/uk/blog/release/v11.7.0/
102
+ if ((0, gte_1.default)(process.version, 'v11.7.0')) {
103
+ // @see https://github.com/facebook/flow/issues/7670
104
+ // @ts-expect-error Node.js version compatibility
105
+ http_1.default.globalAgent = httpAgent;
106
+ // @ts-expect-error Node.js version compatibility
107
+ https_1.default.globalAgent = httpsAgent;
108
+ }
109
+ // The reason this logic is used in addition to overriding http(s).globalAgent
110
+ // is because there is no guarantee that we set http(s).globalAgent variable
111
+ // before an instance of http(s).Agent has been already constructed by someone,
112
+ // e.g. Stripe SDK creates instances of http(s).Agent at the top-level.
113
+ // @see https://github.com/gajus/global-agent/pull/13
114
+ //
115
+ // We still want to override http(s).globalAgent when possible to enable logic
116
+ // in `bindHttpMethod`.
117
+ if ((0, gte_1.default)(process.version, 'v10.0.0')) {
118
+ // @ts-expect-error seems like we are using wrong type for httpAgent
119
+ http_1.default.get = (0, utilities_1.bindHttpMethod)(httpGet, httpAgent, configuration.forceGlobalAgent);
120
+ // @ts-expect-error seems like we are using wrong type for httpAgent
121
+ http_1.default.request = (0, utilities_1.bindHttpMethod)(httpRequest, httpAgent, configuration.forceGlobalAgent);
122
+ // @ts-expect-error seems like we are using wrong type for httpAgent
123
+ https_1.default.get = (0, utilities_1.bindHttpMethod)(httpsGet, httpsAgent, configuration.forceGlobalAgent);
124
+ // @ts-expect-error seems like we are using wrong type for httpAgent
125
+ https_1.default.request = (0, utilities_1.bindHttpMethod)(httpsRequest, httpsAgent, configuration.forceGlobalAgent);
126
+ }
127
+ else {
128
+ log.warn('attempt to initialize global-agent in unsupported Node.js version was ignored');
129
+ }
130
+ return proxyController;
131
+ };
@@ -0,0 +1 @@
1
+ export {};