egg 3.30.1 → 3.32.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/README.md +2 -2
- package/README.zh-CN.md +2 -2
- package/index.d.ts +14 -2
- package/lib/core/fetch_factory.js +56 -0
- package/lib/core/httpclient.js +1 -0
- package/lib/core/httpclient_next.js +7 -2
- package/lib/egg.js +12 -5
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -4,7 +4,7 @@ English | [简体中文](./README.zh-CN.md)
|
|
|
4
4
|
<img src="site/public/assets/egg-banner.png" />
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
|
-
[](https://npmjs.
|
|
7
|
+
[](https://www.npmjs.com/package/egg/v/release-3.x)
|
|
8
8
|
[](http://packagequality.com/#?package=egg)
|
|
9
9
|
[](https://npmjs.org/package/egg)
|
|
10
10
|
[](https://app.fossa.com/projects/git%2Bgithub.com%2Feggjs%2Fegg?ref=badge_shield)
|
|
@@ -37,7 +37,7 @@ $ open http://localhost:7001
|
|
|
37
37
|
|
|
38
38
|
## Documentations
|
|
39
39
|
|
|
40
|
-
- [Documentations](https://eggjs.org/
|
|
40
|
+
- [Documentations](https://v3.eggjs.org/)
|
|
41
41
|
- [Plugins](https://github.com/search?q=topic%3Aegg-plugin&type=Repositories)
|
|
42
42
|
- [Frameworks](https://github.com/search?q=topic%3Aegg-framework&type=Repositories)
|
|
43
43
|
- [Examples](https://github.com/eggjs/examples)
|
package/README.zh-CN.md
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
<img src="site/public/assets/egg-banner.png" />
|
|
5
5
|
</div>
|
|
6
6
|
|
|
7
|
-
[](https://npmjs.
|
|
7
|
+
[](https://www.npmjs.com/package/egg/v/release-3.x)
|
|
8
8
|
[](http://packagequality.com/#?package=egg)
|
|
9
9
|
[](https://npmjs.org/package/egg)
|
|
10
10
|
|
|
@@ -34,7 +34,7 @@ $ open http://localhost:7001
|
|
|
34
34
|
|
|
35
35
|
## 文档
|
|
36
36
|
|
|
37
|
-
- [官方文档](https://eggjs.org/zh-
|
|
37
|
+
- [官方文档](https://v3.eggjs.org/zh-CN/)
|
|
38
38
|
- [插件列表](https://github.com/search?q=topic%3Aegg-plugin&type=Repositories)
|
|
39
39
|
- [框架列表](https://github.com/search?q=topic%3Aegg-framework&type=Repositories)
|
|
40
40
|
- [官方示例](https://github.com/eggjs/examples)
|
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');
|
|
@@ -23,6 +23,10 @@ import {
|
|
|
23
23
|
RequestOptions,
|
|
24
24
|
HttpClientResponse as HttpClientResponseNext,
|
|
25
25
|
} from 'urllib-next';
|
|
26
|
+
import {
|
|
27
|
+
FetchFactory,
|
|
28
|
+
fetch,
|
|
29
|
+
} from 'urllib4';
|
|
26
30
|
import {
|
|
27
31
|
EggCoreBase,
|
|
28
32
|
FileLoaderOption,
|
|
@@ -313,6 +317,8 @@ declare module 'egg' {
|
|
|
313
317
|
useHttpClientNext?: boolean;
|
|
314
318
|
/** Allow to use HTTP2 first, only work on `useHttpClientNext = true`. Default is `false` */
|
|
315
319
|
allowH2?: boolean;
|
|
320
|
+
/** Custom lookup function for DNS resolution */
|
|
321
|
+
lookup?: LookupFunction;
|
|
316
322
|
}
|
|
317
323
|
|
|
318
324
|
export interface EggAppConfig {
|
|
@@ -589,6 +595,12 @@ declare module 'egg' {
|
|
|
589
595
|
*/
|
|
590
596
|
httpclient: EggHttpClient;
|
|
591
597
|
|
|
598
|
+
/**
|
|
599
|
+
* node fetch
|
|
600
|
+
*/
|
|
601
|
+
FetchFactory: FetchFactory;
|
|
602
|
+
fetch: typeof fetch,
|
|
603
|
+
|
|
592
604
|
/**
|
|
593
605
|
* Logger for Application, wrapping app.coreLogger with context infomation
|
|
594
606
|
*
|
|
@@ -1287,4 +1299,4 @@ declare module 'egg' {
|
|
|
1287
1299
|
export interface Singleton<T> {
|
|
1288
1300
|
get(id: string): T;
|
|
1289
1301
|
}
|
|
1290
|
-
}
|
|
1302
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
const debug = require('util').debuglog('egg:lib:core:fetch_factory');
|
|
2
|
+
|
|
3
|
+
const mainNodejsVersion = parseInt(process.versions.node.split('.')[0]);
|
|
4
|
+
let FetchFactory;
|
|
5
|
+
let fetch;
|
|
6
|
+
let fetchInitialized = false;
|
|
7
|
+
let safeFetch;
|
|
8
|
+
let ssrfFetchFactory;
|
|
9
|
+
|
|
10
|
+
if (mainNodejsVersion >= 20) {
|
|
11
|
+
// urllib@4 only works on Node.js >= 20
|
|
12
|
+
try {
|
|
13
|
+
const urllib4 = require('urllib4');
|
|
14
|
+
FetchFactory = urllib4.FetchFactory;
|
|
15
|
+
debug('urllib4 enable');
|
|
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
|
+
|
|
30
|
+
safeFetch = function safeFetch(url, init) {
|
|
31
|
+
if (!ssrfFetchFactory) {
|
|
32
|
+
const ssrfConfig = this.config.security?.ssrf;
|
|
33
|
+
const clientOptions = {};
|
|
34
|
+
if (ssrfConfig?.checkAddress) {
|
|
35
|
+
clientOptions.checkAddress = ssrfConfig.checkAddress;
|
|
36
|
+
} else {
|
|
37
|
+
this.logger.warn('[egg-security] please configure `config.security.ssrf` first');
|
|
38
|
+
}
|
|
39
|
+
if (this.config.httpclient?.lookup) {
|
|
40
|
+
clientOptions.lookup = this.config.httpclient.lookup;
|
|
41
|
+
}
|
|
42
|
+
ssrfFetchFactory = new FetchFactory();
|
|
43
|
+
ssrfFetchFactory.setClientOptions(clientOptions);
|
|
44
|
+
}
|
|
45
|
+
return ssrfFetchFactory.fetch(url, init);
|
|
46
|
+
};
|
|
47
|
+
} catch (err) {
|
|
48
|
+
debug('require urllib4 error: %s', err);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
module.exports = {
|
|
53
|
+
FetchFactory,
|
|
54
|
+
safeFetch,
|
|
55
|
+
fetch,
|
|
56
|
+
};
|
package/lib/core/httpclient.js
CHANGED
|
@@ -5,8 +5,8 @@ const SSRF_HTTPCLIENT = Symbol('SSRF_HTTPCLIENT');
|
|
|
5
5
|
|
|
6
6
|
const mainNodejsVersion = parseInt(process.versions.node.split('.')[0]);
|
|
7
7
|
let HttpClient;
|
|
8
|
-
if (mainNodejsVersion >=
|
|
9
|
-
// urllib@4 only works on Node.js >=
|
|
8
|
+
if (mainNodejsVersion >= 20) {
|
|
9
|
+
// urllib@4 only works on Node.js >= 20
|
|
10
10
|
try {
|
|
11
11
|
HttpClient = require('urllib4').HttpClient;
|
|
12
12
|
debug('urllib4 enable');
|
|
@@ -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,6 +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, fetch } = require('./core/fetch_factory');
|
|
17
18
|
const createLoggers = require('./core/logger');
|
|
18
19
|
const Singleton = require('./core/singleton');
|
|
19
20
|
const utils = require('./core/utils');
|
|
@@ -51,7 +52,11 @@ class EggApplication extends EggCore {
|
|
|
51
52
|
this.ContextHttpClient = ContextHttpClient;
|
|
52
53
|
this.HttpClient = HttpClient;
|
|
53
54
|
this.HttpClientNext = HttpClientNext;
|
|
54
|
-
|
|
55
|
+
this.FetchFactory = FetchFactory;
|
|
56
|
+
if (FetchFactory) {
|
|
57
|
+
this.fetch = fetch.bind(this);
|
|
58
|
+
this.safeFetch = safeFetch.bind(this);
|
|
59
|
+
}
|
|
55
60
|
this.loader.loadConfig();
|
|
56
61
|
|
|
57
62
|
/**
|
|
@@ -290,11 +295,13 @@ class EggApplication extends EggCore {
|
|
|
290
295
|
* Create a new HttpClient instance with custom options
|
|
291
296
|
* @param {Object} [options] HttpClient init options
|
|
292
297
|
*/
|
|
293
|
-
createHttpClient(options) {
|
|
298
|
+
createHttpClient(options = {}) {
|
|
294
299
|
let httpClient;
|
|
300
|
+
options.lookup = options.lookup ?? this.config.httpclient.lookup;
|
|
301
|
+
|
|
295
302
|
if (this.config.httpclient.useHttpClientNext || this.config.httpclient.allowH2) {
|
|
296
303
|
httpClient = new this.HttpClientNext(this, options);
|
|
297
|
-
} else if (this.config.httpclient
|
|
304
|
+
} else if (this.config.httpclient?.enableDNSCache) {
|
|
298
305
|
httpClient = new DNSCacheHttpClient(this, options);
|
|
299
306
|
} else {
|
|
300
307
|
httpClient = new this.HttpClient(this, options);
|
|
@@ -488,7 +495,7 @@ class EggApplication extends EggCore {
|
|
|
488
495
|
return this.config.env;
|
|
489
496
|
}
|
|
490
497
|
/* eslint no-empty-function: off */
|
|
491
|
-
set env(_) {}
|
|
498
|
+
set env(_) { }
|
|
492
499
|
|
|
493
500
|
/**
|
|
494
501
|
* app.proxy delegate app.config.proxy
|
|
@@ -499,7 +506,7 @@ class EggApplication extends EggCore {
|
|
|
499
506
|
return this.config.proxy;
|
|
500
507
|
}
|
|
501
508
|
/* eslint no-empty-function: off */
|
|
502
|
-
set proxy(_) {}
|
|
509
|
+
set proxy(_) { }
|
|
503
510
|
|
|
504
511
|
/**
|
|
505
512
|
* create a singleton instance
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "egg",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.32.0",
|
|
4
4
|
"publishConfig": {
|
|
5
|
-
"tag": "
|
|
5
|
+
"tag": "release-3.x",
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
8
8
|
"description": "A web framework's framework for Node.js",
|
|
@@ -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"
|