global-agent 4.1.2 → 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 -2
  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 -9
  59. package/src/factories/createGlobalProxyAgent.test.ts +0 -761
  60. package/src/factories/createGlobalProxyAgent.ts +0 -187
  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
@@ -1,296 +0,0 @@
1
- import type * as http from 'http';
2
- import type * as https from 'https';
3
- import net from 'net';
4
- import {
5
- serializeError,
6
- } from 'serialize-error';
7
- import {
8
- logger,
9
- } from '../Logger';
10
- import type {
11
- AgentType,
12
- ConnectionCallbackType,
13
- ConnectionConfigurationType,
14
- GetUrlProxyMethodType,
15
- IsProxyConfiguredMethodType,
16
- MustUrlUseProxyMethodType,
17
- ProtocolType,
18
- } from '../types';
19
-
20
- const log = logger.child({
21
- namespace: 'Agent',
22
- });
23
-
24
- let requestId = 0;
25
-
26
- type AgentRequestOptions = {
27
- host?: string,
28
- path?: string,
29
- port: number,
30
- };
31
-
32
- type HttpRequestOptions = AgentRequestOptions & Omit<http.RequestOptions, keyof AgentRequestOptions> & {
33
- secureEndpoint: false,
34
- };
35
-
36
- type HttpsRequestOptions = AgentRequestOptions & Omit<https.RequestOptions, keyof AgentRequestOptions> & {
37
- secureEndpoint: true,
38
- };
39
-
40
- type RequestOptions = HttpRequestOptions | HttpsRequestOptions;
41
-
42
- abstract class Agent {
43
- public defaultPort: number;
44
-
45
- public protocol: ProtocolType;
46
-
47
- public fallbackAgent: AgentType;
48
-
49
- public isProxyConfigured: IsProxyConfiguredMethodType;
50
-
51
- public mustUrlUseProxy: MustUrlUseProxyMethodType;
52
-
53
- public getUrlProxy: GetUrlProxyMethodType;
54
-
55
- public socketConnectionTimeout: number;
56
-
57
- public ca: string[] | string | undefined;
58
-
59
- public constructor (
60
- isProxyConfigured: IsProxyConfiguredMethodType,
61
- mustUrlUseProxy: MustUrlUseProxyMethodType,
62
- getUrlProxy: GetUrlProxyMethodType,
63
- fallbackAgent: AgentType,
64
- socketConnectionTimeout: number,
65
- ca: string[] | string | undefined,
66
- ) {
67
- this.fallbackAgent = fallbackAgent;
68
- this.isProxyConfigured = isProxyConfigured;
69
- this.mustUrlUseProxy = mustUrlUseProxy;
70
- this.getUrlProxy = getUrlProxy;
71
- this.socketConnectionTimeout = socketConnectionTimeout;
72
- this.ca = ca;
73
- }
74
-
75
- /**
76
- * This method can be used to append new ca certificates to existing ca certificates
77
- *
78
- * @param {string[] | string} ca a ca certificate or an array of ca certificates
79
- */
80
- public addCACertificates (ca: string[] | string) {
81
- if (!ca) {
82
- log.error('Invalid input ca certificate');
83
- } else if (this.ca) {
84
- if (typeof ca === typeof this.ca) {
85
- // concat valid ca certificates with the existing certificates,
86
- if (typeof this.ca === 'string') {
87
- this.ca = this.ca.concat(ca as string);
88
- } else {
89
- this.ca = this.ca.concat(ca as string[]);
90
- }
91
- } else {
92
- log.error('Input ca certificate type mismatched with existing ca certificate type');
93
- }
94
- } else {
95
- this.ca = ca;
96
- }
97
- }
98
-
99
- /**
100
- * This method clears existing CA Certificates.
101
- * It sets ca to undefined
102
- */
103
- public clearCACertificates () {
104
- this.ca = undefined;
105
- }
106
-
107
- /**
108
- * Evaluate value for tls reject unauthorized variable
109
- */
110
- public getRejectUnauthorized () {
111
- // oxlint-disable-next-line node/no-process-env
112
- const rejectUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED;
113
- let returnValue = true;
114
- if (typeof rejectUnauthorized === 'boolean') {
115
- returnValue = rejectUnauthorized;
116
- } else if (typeof rejectUnauthorized === 'number') {
117
- returnValue = rejectUnauthorized === 1;
118
- } else if (typeof rejectUnauthorized === 'string') {
119
- returnValue = ['true', 't', 'yes', 'y', 'on', '1'].includes(rejectUnauthorized.trim().toLowerCase());
120
- }
121
-
122
- return returnValue;
123
- }
124
-
125
- public abstract createConnection (configuration: ConnectionConfigurationType, callback: ConnectionCallbackType): void;
126
-
127
- public addRequest (request: http.ClientRequest, configuration: RequestOptions) {
128
- let requestUrl;
129
-
130
- // It is possible that addRequest was constructed for a proxied request already, e.g.
131
- // "request" package does this when it detects that a proxy should be used
132
- // https://github.com/request/request/blob/212570b6971a732b8dd9f3c73354bcdda158a737/request.js#L402
133
- // https://gist.github.com/gajus/e2074cd3b747864ffeaabbd530d30218
134
- if (request.path.startsWith('http://') ?? request.path.startsWith('https://')) {
135
- requestUrl = request.path;
136
- } else if (request.method === 'CONNECT') {
137
- requestUrl = 'https://' + request.path;
138
- } else {
139
- requestUrl = this.protocol + '//' + (configuration.hostname ?? configuration.host) + (configuration.port === 80 || configuration.port === 443 ? '' : ':' + configuration.port) + request.path;
140
- }
141
-
142
- // If a request should go to a local socket, proxying it through an HTTP
143
- // server does not make sense as the information about the target socket
144
- // will be lost and the proxy won't be able to correctly handle the request.
145
- if (configuration.socketPath) {
146
- log.trace({
147
- destination: configuration.socketPath,
148
- }, 'not proxying request; destination is a socket');
149
-
150
- // @ts-expect-error seems like we are using wrong type for fallbackAgent.
151
- this.fallbackAgent.addRequest(request, configuration);
152
-
153
- return;
154
- }
155
-
156
- if (!this.isProxyConfigured()) {
157
- log.trace({
158
- destination: requestUrl,
159
- }, 'not proxying request; GLOBAL_AGENT.HTTP_PROXY is not configured');
160
-
161
- // @ts-expect-error seems like we are using wrong type for fallbackAgent.
162
- this.fallbackAgent.addRequest(request, configuration);
163
-
164
- return;
165
- }
166
-
167
- if (!this.mustUrlUseProxy(requestUrl)) {
168
- log.trace({
169
- destination: requestUrl,
170
- }, 'not proxying request; url matches GLOBAL_AGENT.NO_PROXY');
171
-
172
- // @ts-expect-error seems like we are using wrong type for fallbackAgent.
173
- this.fallbackAgent.addRequest(request, configuration);
174
-
175
- return;
176
- }
177
-
178
- const currentRequestId = requestId++;
179
-
180
- const proxy = this.getUrlProxy(requestUrl);
181
-
182
- if (this.protocol === 'http:') {
183
- request.path = requestUrl;
184
-
185
- if (proxy.authorization) {
186
- request.setHeader('proxy-authorization', 'Basic ' + Buffer.from(proxy.authorization).toString('base64'));
187
- }
188
- }
189
-
190
- log.trace({
191
- destination: requestUrl,
192
- proxy: 'http://' + proxy.hostname + ':' + proxy.port,
193
- requestId: currentRequestId,
194
- }, 'proxying request');
195
-
196
- request.on('error', (error: Error) => {
197
- log.error({
198
- error: serializeError(error),
199
- }, 'request error');
200
- });
201
-
202
- request.once('response', (response: http.IncomingMessage) => {
203
- log.trace({
204
- headers: response.headers,
205
- requestId: currentRequestId,
206
- statusCode: response.statusCode,
207
- }, 'proxying response');
208
- });
209
-
210
- request.shouldKeepAlive = false;
211
-
212
- const connectionConfiguration = {
213
- host: configuration.hostname ?? configuration.host ?? '',
214
- port: configuration.port ?? 80,
215
- proxy,
216
- tls: {},
217
- };
218
-
219
- // add optional tls options for https requests.
220
- // @see https://nodejs.org/docs/latest-v12.x/api/https.html#https_https_request_url_options_callback :
221
- // > The following additional options from tls.connect()
222
- // > - https://nodejs.org/docs/latest-v12.x/api/tls.html#tls_tls_connect_options_callback -
223
- // > are also accepted:
224
- // > ca, cert, ciphers, clientCertEngine, crl, dhparam, ecdhCurve, honorCipherOrder,
225
- // > key, passphrase, pfx, rejectUnauthorized, secureOptions, secureProtocol, servername, sessionIdContext.
226
- if (configuration.secureEndpoint) {
227
- // Determine servername - Node.js doesn't allow IP addresses as servername
228
- const host = configuration.servername ?? connectionConfiguration.host;
229
- const servername = net.isIP(host) ? undefined : host;
230
-
231
- connectionConfiguration.tls = {
232
- ca: configuration.ca ?? this.ca,
233
- cert: configuration.cert,
234
- ciphers: configuration.ciphers,
235
- clientCertEngine: configuration.clientCertEngine,
236
- crl: configuration.crl,
237
- dhparam: configuration.dhparam,
238
- ecdhCurve: configuration.ecdhCurve,
239
- honorCipherOrder: configuration.honorCipherOrder,
240
- key: configuration.key,
241
- passphrase: configuration.passphrase,
242
- pfx: configuration.pfx,
243
- rejectUnauthorized: configuration.rejectUnauthorized ?? this.getRejectUnauthorized(),
244
- secureOptions: configuration.secureOptions,
245
- secureProtocol: configuration.secureProtocol,
246
- servername,
247
- sessionIdContext: configuration.sessionIdContext,
248
- };
249
- }
250
-
251
- this.createConnection(connectionConfiguration, (error, socket) => {
252
- log.trace({
253
- target: connectionConfiguration,
254
- }, 'connecting');
255
-
256
- // @see https://github.com/nodejs/node/issues/5757#issuecomment-305969057
257
- if (socket) {
258
- socket.setTimeout(this.socketConnectionTimeout, () => {
259
- socket.destroy();
260
- });
261
-
262
- socket.once('connect', () => {
263
- log.trace({
264
- target: connectionConfiguration,
265
- }, 'connected');
266
-
267
- socket.setTimeout(0);
268
- });
269
-
270
- socket.once('secureConnect', () => {
271
- log.trace({
272
- target: connectionConfiguration,
273
- }, 'connected (secure)');
274
-
275
- socket.setTimeout(0);
276
- });
277
- }
278
-
279
- if (error) {
280
- request.emit('error', error);
281
- } else if (socket) {
282
- log.debug('created socket');
283
-
284
- socket.on('error', (socketError: Error) => {
285
- log.error({
286
- error: serializeError(socketError),
287
- }, 'socket error');
288
- });
289
-
290
- request.onSocket(socket);
291
- }
292
- });
293
- }
294
- }
295
-
296
- export default Agent;
@@ -1,45 +0,0 @@
1
- import net from 'net';
2
- import type {
3
- AgentType,
4
- ConnectionCallbackType,
5
- ConnectionConfigurationType,
6
- GetUrlProxyMethodType,
7
- IsProxyConfiguredMethodType,
8
- MustUrlUseProxyMethodType,
9
- } from '../types';
10
- import Agent from './Agent';
11
-
12
- class HttpProxyAgent extends Agent {
13
- // @see https://github.com/sindresorhus/eslint-plugin-unicorn/issues/169#issuecomment-486980290
14
- public constructor (
15
- isProxyConfigured: IsProxyConfiguredMethodType,
16
- mustUrlUseProxy: MustUrlUseProxyMethodType,
17
- getUrlProxy: GetUrlProxyMethodType,
18
- fallbackAgent: AgentType,
19
- socketConnectionTimeout: number,
20
- ca: string[] | string | undefined,
21
- ) {
22
- super(
23
- isProxyConfigured,
24
- mustUrlUseProxy,
25
- getUrlProxy,
26
- fallbackAgent,
27
- socketConnectionTimeout,
28
- ca,
29
- );
30
-
31
- this.protocol = 'http:';
32
- this.defaultPort = 80;
33
- }
34
-
35
- public createConnection (configuration: ConnectionConfigurationType, callback: ConnectionCallbackType) {
36
- const socket = net.connect(
37
- configuration.proxy.port,
38
- configuration.proxy.hostname,
39
- );
40
-
41
- callback(null, socket);
42
- }
43
- }
44
-
45
- export default HttpProxyAgent;
@@ -1,83 +0,0 @@
1
- import net from 'net';
2
- import tls from 'tls';
3
- import type {
4
- AgentType,
5
- ConnectionCallbackType,
6
- ConnectionConfigurationType,
7
- GetUrlProxyMethodType,
8
- IsProxyConfiguredMethodType,
9
- MustUrlUseProxyMethodType,
10
- } from '../types';
11
- import Agent from './Agent';
12
-
13
- class HttpsProxyAgent extends Agent {
14
- public constructor (
15
- isProxyConfigured: IsProxyConfiguredMethodType,
16
- mustUrlUseProxy: MustUrlUseProxyMethodType,
17
- getUrlProxy: GetUrlProxyMethodType,
18
- fallbackAgent: AgentType,
19
- socketConnectionTimeout: number,
20
- ca: string[] | string | undefined,
21
- ) {
22
- super(
23
- isProxyConfigured,
24
- mustUrlUseProxy,
25
- getUrlProxy,
26
- fallbackAgent,
27
- socketConnectionTimeout,
28
- ca,
29
- );
30
-
31
- this.protocol = 'https:';
32
- this.defaultPort = 443;
33
- }
34
-
35
- public createConnection (configuration: ConnectionConfigurationType, callback: ConnectionCallbackType) {
36
- const socket = net.connect(
37
- configuration.proxy.port,
38
- configuration.proxy.hostname,
39
- );
40
-
41
- socket.on('error', (error) => {
42
- callback(error);
43
- });
44
-
45
- socket.once('data', (data) => {
46
- // Proxies with HTTPS as protocal are not allowed by parseProxyUrl(), so it should be safe to assume that the response is plain text
47
- const statusLine = data.toString().split('\r\n')[0];
48
- const statusLineExp = /^HTTP\/(\d)\.(\d) (\d{3}) ?(.*)$/;
49
-
50
- const statusCode = statusLineExp.exec(statusLine)?.[3];
51
-
52
- if (typeof statusCode === 'string' && Number(statusCode) >= 400) {
53
- const error = new Error(`Proxy server refused connecting to '${configuration.host}:${configuration.port}' (${statusLine})`);
54
- socket.destroy();
55
- callback(error);
56
-
57
- return;
58
- }
59
-
60
- const secureSocket = tls.connect({
61
- ...configuration.tls,
62
- socket,
63
- });
64
-
65
- callback(null, secureSocket);
66
- });
67
-
68
- let connectMessage = '';
69
-
70
- connectMessage += 'CONNECT ' + configuration.host + ':' + configuration.port + ' HTTP/1.1\r\n';
71
- connectMessage += 'Host: ' + configuration.host + ':' + configuration.port + '\r\n';
72
-
73
- if (configuration.proxy.authorization) {
74
- connectMessage += 'Proxy-Authorization: Basic ' + Buffer.from(configuration.proxy.authorization).toString('base64') + '\r\n';
75
- }
76
-
77
- connectMessage += '\r\n';
78
-
79
- socket.write(connectMessage);
80
- }
81
- }
82
-
83
- export default HttpsProxyAgent;
@@ -1,9 +0,0 @@
1
- export {
2
- default as Agent,
3
- } from './Agent';
4
- export {
5
- default as HttpProxyAgent,
6
- } from './HttpProxyAgent';
7
- export {
8
- default as HttpsProxyAgent,
9
- } from './HttpsProxyAgent';
package/src/errors.ts DELETED
@@ -1,9 +0,0 @@
1
- export class UnexpectedStateError extends Error {
2
- public code: string;
3
-
4
- public constructor (message: string, code: string = 'UNEXPECTED_STATE_ERROR') {
5
- super(message);
6
-
7
- this.code = code;
8
- }
9
- }