egg 3.31.0 → 3.33.0
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.
- package/index.d.ts +4 -2
- package/lib/core/fetch_factory.js +20 -1
- package/lib/core/httpclient.js +1 -0
- package/lib/core/httpclient_next.js +5 -0
- package/lib/egg.js +53 -9
- package/package.json +3 -3
package/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ import accepts = require('accepts');
|
|
|
2
2
|
import { AsyncLocalStorage } from 'async_hooks';
|
|
3
3
|
import { EventEmitter } from 'events'
|
|
4
4
|
import { Readable } from 'stream';
|
|
5
|
-
import { Socket } from 'net';
|
|
5
|
+
import { Socket, LookupFunction } from 'net';
|
|
6
6
|
import { IncomingMessage, ServerResponse } from 'http';
|
|
7
7
|
import KoaApplication = require('koa');
|
|
8
8
|
import KoaRouter = require('koa-router');
|
|
@@ -317,6 +317,8 @@ declare module 'egg' {
|
|
|
317
317
|
useHttpClientNext?: boolean;
|
|
318
318
|
/** Allow to use HTTP2 first, only work on `useHttpClientNext = true`. Default is `false` */
|
|
319
319
|
allowH2?: boolean;
|
|
320
|
+
/** Custom lookup function for DNS resolution */
|
|
321
|
+
lookup?: LookupFunction;
|
|
320
322
|
}
|
|
321
323
|
|
|
322
324
|
export interface EggAppConfig {
|
|
@@ -1297,4 +1299,4 @@ declare module 'egg' {
|
|
|
1297
1299
|
export interface Singleton<T> {
|
|
1298
1300
|
get(id: string): T;
|
|
1299
1301
|
}
|
|
1300
|
-
}
|
|
1302
|
+
}
|
|
@@ -2,6 +2,8 @@ const debug = require('util').debuglog('egg:lib:core:fetch_factory');
|
|
|
2
2
|
|
|
3
3
|
const mainNodejsVersion = parseInt(process.versions.node.split('.')[0]);
|
|
4
4
|
let FetchFactory;
|
|
5
|
+
let fetch;
|
|
6
|
+
let fetchInitialized = false;
|
|
5
7
|
let safeFetch;
|
|
6
8
|
let ssrfFetchFactory;
|
|
7
9
|
|
|
@@ -12,15 +14,31 @@ if (mainNodejsVersion >= 20) {
|
|
|
12
14
|
FetchFactory = urllib4.FetchFactory;
|
|
13
15
|
debug('urllib4 enable');
|
|
14
16
|
|
|
17
|
+
|
|
18
|
+
fetch = function fetch(url, init) {
|
|
19
|
+
if (!fetchInitialized) {
|
|
20
|
+
const clientOptions = {};
|
|
21
|
+
if (this.config.httpclient?.lookup) {
|
|
22
|
+
clientOptions.lookup = this.config.httpclient.lookup;
|
|
23
|
+
}
|
|
24
|
+
FetchFactory.setClientOptions(clientOptions);
|
|
25
|
+
fetchInitialized = true;
|
|
26
|
+
}
|
|
27
|
+
return FetchFactory.fetch(url, init);
|
|
28
|
+
};
|
|
29
|
+
|
|
15
30
|
safeFetch = function safeFetch(url, init) {
|
|
16
31
|
if (!ssrfFetchFactory) {
|
|
17
|
-
const ssrfConfig = this.config.security
|
|
32
|
+
const ssrfConfig = this.config.security?.ssrf;
|
|
18
33
|
const clientOptions = {};
|
|
19
34
|
if (ssrfConfig?.checkAddress) {
|
|
20
35
|
clientOptions.checkAddress = ssrfConfig.checkAddress;
|
|
21
36
|
} else {
|
|
22
37
|
this.logger.warn('[egg-security] please configure `config.security.ssrf` first');
|
|
23
38
|
}
|
|
39
|
+
if (this.config.httpclient?.lookup) {
|
|
40
|
+
clientOptions.lookup = this.config.httpclient.lookup;
|
|
41
|
+
}
|
|
24
42
|
ssrfFetchFactory = new FetchFactory();
|
|
25
43
|
ssrfFetchFactory.setClientOptions(clientOptions);
|
|
26
44
|
}
|
|
@@ -34,4 +52,5 @@ if (mainNodejsVersion >= 20) {
|
|
|
34
52
|
module.exports = {
|
|
35
53
|
FetchFactory,
|
|
36
54
|
safeFetch,
|
|
55
|
+
fetch,
|
|
37
56
|
};
|
package/lib/core/httpclient.js
CHANGED
|
@@ -32,6 +32,7 @@ class HttpClientNext extends HttpClient {
|
|
|
32
32
|
app,
|
|
33
33
|
defaultArgs: options.request,
|
|
34
34
|
allowH2: options.allowH2,
|
|
35
|
+
lookup: options.lookup ?? app.config.httpclient?.lookup,
|
|
35
36
|
// use on egg-security ssrf
|
|
36
37
|
// https://github.com/eggjs/egg-security/blob/master/lib/extend/safe_curl.js#L11
|
|
37
38
|
checkAddress: options.checkAddress,
|
|
@@ -62,8 +63,12 @@ class HttpClientNext extends HttpClient {
|
|
|
62
63
|
} else {
|
|
63
64
|
this.app.logger.warn('[egg-security] please configure `config.security.ssrf` first');
|
|
64
65
|
}
|
|
66
|
+
if (!options.lookup && this.app.config.httpclient.lookup) {
|
|
67
|
+
options.lookup = this.app.config.httpclient.lookup;
|
|
68
|
+
}
|
|
65
69
|
this[SSRF_HTTPCLIENT] = new HttpClientNext(this.app, {
|
|
66
70
|
checkAddress: ssrfConfig.checkAddress,
|
|
71
|
+
lookup: options.lookup,
|
|
67
72
|
});
|
|
68
73
|
}
|
|
69
74
|
return await this[SSRF_HTTPCLIENT].request(url, options);
|
package/lib/egg.js
CHANGED
|
@@ -14,7 +14,7 @@ const Messenger = require('./core/messenger');
|
|
|
14
14
|
const DNSCacheHttpClient = require('./core/dnscache_httpclient');
|
|
15
15
|
const HttpClient = require('./core/httpclient');
|
|
16
16
|
const HttpClientNext = require('./core/httpclient_next');
|
|
17
|
-
const { FetchFactory, safeFetch } = require('./core/fetch_factory');
|
|
17
|
+
const { FetchFactory, safeFetch, fetch } = require('./core/fetch_factory');
|
|
18
18
|
const createLoggers = require('./core/logger');
|
|
19
19
|
const Singleton = require('./core/singleton');
|
|
20
20
|
const utils = require('./core/utils');
|
|
@@ -54,11 +54,9 @@ class EggApplication extends EggCore {
|
|
|
54
54
|
this.HttpClientNext = HttpClientNext;
|
|
55
55
|
this.FetchFactory = FetchFactory;
|
|
56
56
|
if (FetchFactory) {
|
|
57
|
-
this.
|
|
58
|
-
this.fetch = FetchFactory.fetch;
|
|
57
|
+
this.fetch = fetch.bind(this);
|
|
59
58
|
this.safeFetch = safeFetch.bind(this);
|
|
60
59
|
}
|
|
61
|
-
|
|
62
60
|
this.loader.loadConfig();
|
|
63
61
|
|
|
64
62
|
/**
|
|
@@ -297,18 +295,64 @@ class EggApplication extends EggCore {
|
|
|
297
295
|
* Create a new HttpClient instance with custom options
|
|
298
296
|
* @param {Object} [options] HttpClient init options
|
|
299
297
|
*/
|
|
300
|
-
createHttpClient(options) {
|
|
298
|
+
createHttpClient(options = {}) {
|
|
301
299
|
let httpClient;
|
|
302
300
|
if (this.config.httpclient.useHttpClientNext || this.config.httpclient.allowH2) {
|
|
303
|
-
httpClient =
|
|
304
|
-
} else if (this.config.httpclient
|
|
301
|
+
httpClient = this._createHttpClientNextProxy(options);
|
|
302
|
+
} else if (this.config.httpclient?.enableDNSCache) {
|
|
305
303
|
httpClient = new DNSCacheHttpClient(this, options);
|
|
306
304
|
} else {
|
|
305
|
+
options.lookup = options.lookup ?? this.config.httpclient.lookup;
|
|
307
306
|
httpClient = new this.HttpClient(this, options);
|
|
308
307
|
}
|
|
309
308
|
return httpClient;
|
|
310
309
|
}
|
|
311
310
|
|
|
311
|
+
_createHttpClientNextProxy(options = {}) {
|
|
312
|
+
const self = this;
|
|
313
|
+
let realClient = null;
|
|
314
|
+
const init = () => {
|
|
315
|
+
if (realClient) return;
|
|
316
|
+
options.lookup = options.lookup ?? self.config.httpclient.lookup;
|
|
317
|
+
realClient = new self.HttpClientNext(self, options);
|
|
318
|
+
};
|
|
319
|
+
return new Proxy({}, {
|
|
320
|
+
get(_target, prop) {
|
|
321
|
+
init();
|
|
322
|
+
const value = realClient[prop];
|
|
323
|
+
if (typeof value === 'function') {
|
|
324
|
+
return value.bind(realClient);
|
|
325
|
+
}
|
|
326
|
+
return value;
|
|
327
|
+
},
|
|
328
|
+
set(_target, prop, value) {
|
|
329
|
+
init();
|
|
330
|
+
realClient[prop] = value;
|
|
331
|
+
return true;
|
|
332
|
+
},
|
|
333
|
+
has(_target, prop) {
|
|
334
|
+
init();
|
|
335
|
+
return prop in realClient;
|
|
336
|
+
},
|
|
337
|
+
ownKeys() {
|
|
338
|
+
init();
|
|
339
|
+
return Reflect.ownKeys(realClient);
|
|
340
|
+
},
|
|
341
|
+
getOwnPropertyDescriptor(_target, prop) {
|
|
342
|
+
init();
|
|
343
|
+
return Object.getOwnPropertyDescriptor(realClient, prop);
|
|
344
|
+
},
|
|
345
|
+
deleteProperty(_target, prop) {
|
|
346
|
+
init();
|
|
347
|
+
return delete realClient[prop];
|
|
348
|
+
},
|
|
349
|
+
getPrototypeOf() {
|
|
350
|
+
init();
|
|
351
|
+
return Object.getPrototypeOf(realClient);
|
|
352
|
+
},
|
|
353
|
+
});
|
|
354
|
+
}
|
|
355
|
+
|
|
312
356
|
/**
|
|
313
357
|
* HttpClient instance
|
|
314
358
|
* @see https://github.com/node-modules/urllib
|
|
@@ -495,7 +539,7 @@ class EggApplication extends EggCore {
|
|
|
495
539
|
return this.config.env;
|
|
496
540
|
}
|
|
497
541
|
/* eslint no-empty-function: off */
|
|
498
|
-
set env(_) {}
|
|
542
|
+
set env(_) { }
|
|
499
543
|
|
|
500
544
|
/**
|
|
501
545
|
* app.proxy delegate app.config.proxy
|
|
@@ -506,7 +550,7 @@ class EggApplication extends EggCore {
|
|
|
506
550
|
return this.config.proxy;
|
|
507
551
|
}
|
|
508
552
|
/* eslint no-empty-function: off */
|
|
509
|
-
set proxy(_) {}
|
|
553
|
+
set proxy(_) { }
|
|
510
554
|
|
|
511
555
|
/**
|
|
512
556
|
* create a singleton instance
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "egg",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.33.0",
|
|
4
4
|
"publishConfig": {
|
|
5
5
|
"tag": "release-3.x",
|
|
6
6
|
"access": "public"
|
|
@@ -79,10 +79,10 @@
|
|
|
79
79
|
"eslint": "^8.23.1",
|
|
80
80
|
"eslint-config-egg": "^12.0.0",
|
|
81
81
|
"formstream": "^1.1.1",
|
|
82
|
-
"https-pem": "^3.0.0",
|
|
83
82
|
"jsdoc": "^3.6.11",
|
|
84
83
|
"koa": "^2.13.4",
|
|
85
84
|
"koa-static": "^5.0.0",
|
|
85
|
+
"node-forge": "^1.3.3",
|
|
86
86
|
"node-libs-browser": "^2.2.1",
|
|
87
87
|
"pedding": "^1.1.0",
|
|
88
88
|
"prettier": "^2.7.1",
|
|
@@ -126,7 +126,7 @@
|
|
|
126
126
|
"homepage": "https://github.com/eggjs/egg",
|
|
127
127
|
"repository": {
|
|
128
128
|
"type": "git",
|
|
129
|
-
"url": "https://github.com/eggjs/egg.git"
|
|
129
|
+
"url": "git+https://github.com/eggjs/egg.git"
|
|
130
130
|
},
|
|
131
131
|
"engines": {
|
|
132
132
|
"node": ">= 14.20.0"
|