egg 3.29.0 → 4.0.0-beta.10
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 -1
- package/README.zh-CN.md +7 -5
- package/dist/commonjs/agent.d.ts +4 -0
- package/dist/commonjs/agent.js +10 -0
- package/dist/commonjs/app/extend/context.d.ts +154 -0
- package/dist/commonjs/app/extend/context.js +261 -0
- package/dist/commonjs/app/extend/context.types.d.ts +16 -0
- package/dist/commonjs/app/extend/context.types.js +3 -0
- package/dist/commonjs/app/extend/helper.d.ts +37 -0
- package/dist/commonjs/app/extend/helper.js +49 -0
- package/dist/commonjs/app/extend/request.d.ts +128 -0
- package/dist/commonjs/app/extend/request.js +270 -0
- package/dist/commonjs/app/extend/response.d.ts +25 -0
- package/dist/commonjs/app/extend/response.js +37 -0
- package/dist/commonjs/app/middleware/body_parser.d.ts +2 -0
- package/dist/commonjs/app/middleware/body_parser.js +8 -0
- package/dist/commonjs/app/middleware/meta.d.ts +10 -0
- package/dist/commonjs/app/middleware/meta.js +22 -0
- package/dist/commonjs/app/middleware/notfound.d.ts +7 -0
- package/dist/commonjs/app/middleware/notfound.js +31 -0
- package/dist/commonjs/app/middleware/override_method.d.ts +2 -0
- package/dist/commonjs/app/middleware/override_method.js +8 -0
- package/dist/commonjs/app/middleware/site_file.d.ts +9 -0
- package/dist/commonjs/app/middleware/site_file.js +58 -0
- package/dist/commonjs/config/config.default.d.ts +9 -0
- package/dist/commonjs/config/config.default.js +379 -0
- package/dist/commonjs/config/config.local.d.ts +8 -0
- package/dist/commonjs/config/config.local.js +12 -0
- package/dist/commonjs/config/config.unittest.d.ts +7 -0
- package/dist/commonjs/config/config.unittest.js +11 -0
- package/dist/commonjs/config/plugin.d.ts +122 -0
- package/dist/commonjs/config/plugin.js +125 -0
- package/dist/commonjs/index.d.ts +63 -0
- package/dist/commonjs/index.js +91 -0
- package/dist/commonjs/lib/agent.d.ts +19 -0
- package/dist/commonjs/lib/agent.js +58 -0
- package/dist/commonjs/lib/application.d.ts +59 -0
- package/dist/commonjs/lib/application.js +270 -0
- package/dist/commonjs/lib/core/base_context_class.d.ts +14 -0
- package/dist/commonjs/lib/core/base_context_class.js +22 -0
- package/dist/commonjs/lib/core/base_context_logger.d.ts +36 -0
- package/dist/commonjs/lib/core/base_context_logger.js +64 -0
- package/dist/commonjs/lib/core/base_hook_class.d.ts +11 -0
- package/dist/commonjs/lib/core/base_hook_class.js +30 -0
- package/dist/commonjs/lib/core/context_httpclient.d.ts +16 -0
- package/dist/commonjs/lib/core/context_httpclient.js +30 -0
- package/dist/commonjs/lib/core/httpclient.d.ts +13 -0
- package/dist/commonjs/lib/core/httpclient.js +37 -0
- package/dist/commonjs/lib/core/logger.d.ts +3 -0
- package/dist/commonjs/lib/core/logger.js +40 -0
- package/dist/commonjs/lib/core/messenger/IMessenger.d.ts +50 -0
- package/dist/commonjs/lib/core/messenger/IMessenger.js +3 -0
- package/dist/commonjs/lib/core/messenger/index.d.ts +7 -0
- package/dist/commonjs/lib/core/messenger/index.js +14 -0
- package/dist/commonjs/lib/core/messenger/ipc.d.ts +59 -0
- package/dist/commonjs/lib/core/messenger/ipc.js +137 -0
- package/dist/commonjs/lib/core/messenger/local.d.ts +61 -0
- package/dist/commonjs/lib/core/messenger/local.js +137 -0
- package/dist/commonjs/lib/core/singleton.d.ts +23 -0
- package/dist/commonjs/lib/core/singleton.js +120 -0
- package/dist/commonjs/lib/core/utils.d.ts +2 -0
- package/dist/commonjs/lib/core/utils.js +77 -0
- package/dist/commonjs/lib/egg.d.ts +276 -0
- package/dist/commonjs/lib/egg.js +617 -0
- package/dist/commonjs/lib/egg.types.d.ts +6 -0
- package/dist/commonjs/lib/egg.types.js +3 -0
- package/dist/commonjs/lib/loader/AgentWorkerLoader.d.ts +12 -0
- package/dist/commonjs/lib/loader/AgentWorkerLoader.js +24 -0
- package/dist/commonjs/lib/loader/AppWorkerLoader.d.ts +17 -0
- package/dist/commonjs/lib/loader/AppWorkerLoader.js +43 -0
- package/dist/commonjs/lib/loader/EggApplicationLoader.d.ts +4 -0
- package/dist/commonjs/lib/loader/EggApplicationLoader.js +8 -0
- package/dist/commonjs/lib/loader/index.d.ts +3 -0
- package/dist/commonjs/lib/loader/index.js +22 -0
- package/dist/commonjs/lib/start.d.ts +15 -0
- package/dist/commonjs/lib/start.js +49 -0
- package/dist/commonjs/lib/type.d.ts +293 -0
- package/dist/commonjs/lib/type.js +3 -0
- package/dist/commonjs/lib/utils.d.ts +2 -0
- package/dist/commonjs/lib/utils.js +21 -0
- package/dist/commonjs/package.json +3 -0
- package/dist/esm/agent.d.ts +4 -0
- package/dist/esm/agent.js +7 -0
- package/dist/esm/app/extend/context.d.ts +154 -0
- package/dist/esm/app/extend/context.js +255 -0
- package/dist/esm/app/extend/context.types.d.ts +16 -0
- package/dist/esm/app/extend/context.types.js +2 -0
- package/dist/esm/app/extend/helper.d.ts +37 -0
- package/dist/esm/app/extend/helper.js +43 -0
- package/dist/esm/app/extend/request.d.ts +128 -0
- package/dist/esm/app/extend/request.js +264 -0
- package/dist/esm/app/extend/response.d.ts +25 -0
- package/dist/esm/app/extend/response.js +34 -0
- package/dist/esm/app/middleware/body_parser.d.ts +2 -0
- package/dist/esm/app/middleware/body_parser.js +3 -0
- package/dist/esm/app/middleware/meta.d.ts +10 -0
- package/dist/esm/app/middleware/meta.js +20 -0
- package/dist/esm/app/middleware/notfound.d.ts +7 -0
- package/dist/esm/app/middleware/notfound.js +29 -0
- package/dist/esm/app/middleware/override_method.d.ts +2 -0
- package/dist/esm/app/middleware/override_method.js +3 -0
- package/dist/esm/app/middleware/site_file.d.ts +9 -0
- package/dist/esm/app/middleware/site_file.js +53 -0
- package/dist/esm/config/config.default.d.ts +9 -0
- package/dist/esm/config/config.default.js +374 -0
- package/dist/esm/config/config.local.d.ts +8 -0
- package/dist/esm/config/config.local.js +10 -0
- package/dist/esm/config/config.unittest.d.ts +7 -0
- package/dist/esm/config/config.unittest.js +9 -0
- package/dist/esm/config/favicon.png +0 -0
- package/dist/esm/config/plugin.d.ts +122 -0
- package/dist/esm/config/plugin.js +123 -0
- package/dist/esm/index.d.ts +63 -0
- package/dist/esm/index.js +66 -0
- package/dist/esm/lib/agent.d.ts +19 -0
- package/dist/esm/lib/agent.js +54 -0
- package/dist/esm/lib/application.d.ts +59 -0
- package/dist/esm/lib/application.js +263 -0
- package/dist/esm/lib/core/base_context_class.d.ts +14 -0
- package/dist/esm/lib/core/base_context_class.js +18 -0
- package/dist/esm/lib/core/base_context_logger.d.ts +36 -0
- package/dist/esm/lib/core/base_context_logger.js +60 -0
- package/dist/esm/lib/core/base_hook_class.d.ts +11 -0
- package/dist/esm/lib/core/base_hook_class.js +23 -0
- package/dist/esm/lib/core/context_httpclient.d.ts +16 -0
- package/dist/esm/lib/core/context_httpclient.js +26 -0
- package/dist/esm/lib/core/httpclient.d.ts +13 -0
- package/dist/esm/lib/core/httpclient.js +33 -0
- package/dist/esm/lib/core/logger.d.ts +3 -0
- package/dist/esm/lib/core/logger.js +37 -0
- package/dist/esm/lib/core/messenger/IMessenger.d.ts +50 -0
- package/dist/esm/lib/core/messenger/IMessenger.js +2 -0
- package/dist/esm/lib/core/messenger/index.d.ts +7 -0
- package/dist/esm/lib/core/messenger/index.js +11 -0
- package/dist/esm/lib/core/messenger/ipc.d.ts +59 -0
- package/dist/esm/lib/core/messenger/ipc.js +130 -0
- package/dist/esm/lib/core/messenger/local.d.ts +61 -0
- package/dist/esm/lib/core/messenger/local.js +130 -0
- package/dist/esm/lib/core/singleton.d.ts +23 -0
- package/dist/esm/lib/core/singleton.js +113 -0
- package/dist/esm/lib/core/utils.d.ts +2 -0
- package/dist/esm/lib/core/utils.js +70 -0
- package/dist/esm/lib/egg.d.ts +276 -0
- package/dist/esm/lib/egg.js +574 -0
- package/dist/esm/lib/egg.types.d.ts +6 -0
- package/dist/esm/lib/egg.types.js +2 -0
- package/dist/esm/lib/loader/AgentWorkerLoader.d.ts +12 -0
- package/dist/esm/lib/loader/AgentWorkerLoader.js +20 -0
- package/dist/esm/lib/loader/AppWorkerLoader.d.ts +17 -0
- package/dist/esm/lib/loader/AppWorkerLoader.js +39 -0
- package/dist/esm/lib/loader/EggApplicationLoader.d.ts +4 -0
- package/dist/esm/lib/loader/EggApplicationLoader.js +4 -0
- package/dist/esm/lib/loader/index.d.ts +3 -0
- package/dist/esm/lib/loader/index.js +4 -0
- package/dist/esm/lib/start.d.ts +15 -0
- package/dist/esm/lib/start.js +43 -0
- package/dist/esm/lib/type.d.ts +293 -0
- package/dist/esm/lib/type.js +2 -0
- package/dist/esm/lib/utils.d.ts +2 -0
- package/dist/esm/lib/utils.js +14 -0
- package/dist/esm/package.json +3 -0
- package/dist/package.json +4 -0
- package/package.json +97 -79
- package/src/agent.ts +7 -0
- package/src/app/extend/context.ts +303 -0
- package/src/app/extend/context.types.ts +24 -0
- package/{app/extend/helper.js → src/app/extend/helper.ts} +14 -13
- package/{app/extend/request.js → src/app/extend/request.ts} +81 -79
- package/src/app/extend/response.ts +36 -0
- package/src/app/middleware/body_parser.ts +3 -0
- package/{app/middleware/meta.js → src/app/middleware/meta.ts} +11 -4
- package/{app/middleware/notfound.js → src/app/middleware/notfound.ts} +8 -3
- package/src/app/middleware/override_method.ts +3 -0
- package/src/app/middleware/site_file.ts +68 -0
- package/{config/config.default.js → src/config/config.default.ts} +25 -45
- package/src/config/config.local.ts +11 -0
- package/src/config/config.unittest.ts +10 -0
- package/src/config/favicon.png +0 -0
- package/{config/plugin.js → src/config/plugin.ts} +3 -5
- package/src/index.ts +80 -0
- package/src/lib/agent.ts +66 -0
- package/{lib/application.js → src/lib/application.ts} +76 -124
- package/src/lib/core/base_context_class.ts +21 -0
- package/src/lib/core/base_context_logger.ts +67 -0
- package/src/lib/core/base_hook_class.ts +30 -0
- package/src/lib/core/context_httpclient.ts +33 -0
- package/src/lib/core/httpclient.ts +51 -0
- package/src/lib/core/logger.ts +42 -0
- package/src/lib/core/messenger/IMessenger.ts +58 -0
- package/src/lib/core/messenger/index.ts +15 -0
- package/src/lib/core/messenger/ipc.ts +148 -0
- package/{lib/core/messenger/local.js → src/lib/core/messenger/local.ts} +36 -28
- package/{lib/core/singleton.js → src/lib/core/singleton.ts} +56 -33
- package/src/lib/core/utils.ts +77 -0
- package/{lib/egg.js → src/lib/egg.ts} +287 -221
- package/src/lib/egg.types.ts +6 -0
- package/src/lib/loader/AgentWorkerLoader.ts +21 -0
- package/src/lib/loader/AppWorkerLoader.ts +42 -0
- package/src/lib/loader/EggApplicationLoader.ts +5 -0
- package/src/lib/loader/index.ts +3 -0
- package/src/lib/start.ts +56 -0
- package/src/lib/type.ts +329 -0
- package/src/lib/utils.ts +16 -0
- package/CHANGELOG.md +0 -2395
- package/History.md +0 -52
- package/agent.js +0 -11
- package/app/extend/context.js +0 -285
- package/app/extend/response.js +0 -101
- package/app/middleware/body_parser.js +0 -3
- package/app/middleware/override_method.js +0 -3
- package/app/middleware/site_file.js +0 -31
- package/config/config.local.js +0 -7
- package/config/config.unittest.js +0 -8
- package/index.d.ts +0 -1288
- package/index.js +0 -68
- package/lib/agent.js +0 -95
- package/lib/core/base_context_class.js +0 -20
- package/lib/core/base_context_logger.js +0 -64
- package/lib/core/base_hook_class.js +0 -31
- package/lib/core/context_httpclient.js +0 -26
- package/lib/core/dnscache_httpclient.js +0 -93
- package/lib/core/httpclient.js +0 -119
- package/lib/core/httpclient_next.js +0 -80
- package/lib/core/logger.js +0 -35
- package/lib/core/messenger/index.js +0 -14
- package/lib/core/messenger/ipc.js +0 -141
- package/lib/core/utils.js +0 -73
- package/lib/loader/agent_worker_loader.js +0 -27
- package/lib/loader/app_worker_loader.js +0 -48
- package/lib/loader/index.js +0 -5
- package/lib/start.js +0 -39
- /package/{config → dist/commonjs/config}/favicon.png +0 -0
|
@@ -1,17 +1,21 @@
|
|
|
1
|
-
|
|
1
|
+
import querystring from 'node:querystring';
|
|
2
|
+
import { Request as EggCoreRequest } from '@eggjs/core';
|
|
3
|
+
import type { Application } from '../../lib/application.js';
|
|
4
|
+
import type { ContextDelegation } from './context.js';
|
|
5
|
+
import Response from './response.js';
|
|
2
6
|
|
|
3
|
-
const
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
const
|
|
7
|
-
const
|
|
8
|
-
const PROTOCOL = Symbol('PROTOCOL');
|
|
9
|
-
const HOST = Symbol('HOST');
|
|
10
|
-
const ACCEPTS = Symbol('ACCEPTS');
|
|
11
|
-
const IPS = Symbol('IPS');
|
|
7
|
+
const QUERY_CACHE = Symbol('request query cache');
|
|
8
|
+
const QUERIES_CACHE = Symbol('request queries cache');
|
|
9
|
+
const PROTOCOL = Symbol('request protocol');
|
|
10
|
+
const HOST = Symbol('request host');
|
|
11
|
+
const IPS = Symbol('request ips');
|
|
12
12
|
const RE_ARRAY_KEY = /[^\[\]]+\[\]$/;
|
|
13
13
|
|
|
14
|
-
|
|
14
|
+
export default class Request extends EggCoreRequest {
|
|
15
|
+
declare app: Application;
|
|
16
|
+
declare ctx: ContextDelegation;
|
|
17
|
+
declare response: Response;
|
|
18
|
+
|
|
15
19
|
/**
|
|
16
20
|
* Parse the "Host" header field host
|
|
17
21
|
* and support X-Forwarded-Host when a
|
|
@@ -29,17 +33,19 @@ module.exports = {
|
|
|
29
33
|
* => 'demo.eggjs.org'
|
|
30
34
|
* ```
|
|
31
35
|
*/
|
|
32
|
-
get host() {
|
|
33
|
-
|
|
36
|
+
get host(): string {
|
|
37
|
+
let host = this[HOST] as string | undefined;
|
|
38
|
+
if (host) {
|
|
39
|
+
return host;
|
|
40
|
+
}
|
|
34
41
|
|
|
35
|
-
let host;
|
|
36
42
|
if (this.app.config.proxy) {
|
|
37
43
|
host = getFromHeaders(this, this.app.config.hostHeaders);
|
|
38
44
|
}
|
|
39
45
|
host = host || this.get('host') || '';
|
|
40
|
-
this[HOST] = host.split(
|
|
41
|
-
return
|
|
42
|
-
}
|
|
46
|
+
this[HOST] = host = host.split(',')[0].trim();
|
|
47
|
+
return host;
|
|
48
|
+
}
|
|
43
49
|
|
|
44
50
|
/**
|
|
45
51
|
* @member {String} Request#protocol
|
|
@@ -49,25 +55,28 @@ module.exports = {
|
|
|
49
55
|
* => 'https'
|
|
50
56
|
* ```
|
|
51
57
|
*/
|
|
52
|
-
get protocol() {
|
|
53
|
-
|
|
58
|
+
get protocol(): string {
|
|
59
|
+
let protocol = this[PROTOCOL] as string;
|
|
60
|
+
if (protocol) {
|
|
61
|
+
return protocol;
|
|
62
|
+
}
|
|
54
63
|
// detect encrypted socket
|
|
55
|
-
if (this.socket
|
|
56
|
-
this[PROTOCOL] = 'https';
|
|
57
|
-
return
|
|
64
|
+
if (this.socket?.encrypted) {
|
|
65
|
+
this[PROTOCOL] = protocol = 'https';
|
|
66
|
+
return protocol;
|
|
58
67
|
}
|
|
59
68
|
// get from headers specified in `app.config.protocolHeaders`
|
|
60
69
|
if (this.app.config.proxy) {
|
|
61
70
|
const proto = getFromHeaders(this, this.app.config.protocolHeaders);
|
|
62
71
|
if (proto) {
|
|
63
|
-
this[PROTOCOL] = proto.split(/\s*,\s*/)[0];
|
|
64
|
-
return
|
|
72
|
+
this[PROTOCOL] = protocol = proto.split(/\s*,\s*/)[0];
|
|
73
|
+
return protocol;
|
|
65
74
|
}
|
|
66
75
|
}
|
|
67
|
-
// use protocol specified in `app.
|
|
68
|
-
this[PROTOCOL] = this.app.config.protocol || 'http';
|
|
69
|
-
return
|
|
70
|
-
}
|
|
76
|
+
// use protocol specified in `app.config.protocol`
|
|
77
|
+
this[PROTOCOL] = protocol = this.app.config.protocol || 'http';
|
|
78
|
+
return protocol;
|
|
79
|
+
}
|
|
71
80
|
|
|
72
81
|
/**
|
|
73
82
|
* Get all pass through ip addresses from the request.
|
|
@@ -80,29 +89,34 @@ module.exports = {
|
|
|
80
89
|
* => ['100.23.1.2', '201.10.10.2']
|
|
81
90
|
* ```
|
|
82
91
|
*/
|
|
83
|
-
get ips() {
|
|
84
|
-
|
|
92
|
+
get ips(): string[] {
|
|
93
|
+
let ips = this[IPS] as string[] | undefined;
|
|
94
|
+
if (ips) {
|
|
95
|
+
return ips;
|
|
96
|
+
}
|
|
85
97
|
|
|
86
98
|
// return empty array when proxy=false
|
|
87
99
|
if (!this.app.config.proxy) {
|
|
88
|
-
this[IPS] = [];
|
|
89
|
-
return
|
|
100
|
+
this[IPS] = ips = [];
|
|
101
|
+
return ips;
|
|
90
102
|
}
|
|
91
103
|
|
|
92
|
-
const val = getFromHeaders(this, this.app.config.ipHeaders)
|
|
93
|
-
this[IPS] = val ? val.split(/\s*,\s*/) : [];
|
|
104
|
+
const val = getFromHeaders(this, this.app.config.ipHeaders);
|
|
105
|
+
this[IPS] = ips = val ? val.split(/\s*,\s*/) : [];
|
|
94
106
|
|
|
95
107
|
let maxIpsCount = this.app.config.maxIpsCount;
|
|
96
108
|
// Compatible with maxProxyCount logic (previous logic is wrong, only for compatibility with legacy logic)
|
|
97
|
-
if (!maxIpsCount && this.app.config.maxProxyCount)
|
|
109
|
+
if (!maxIpsCount && this.app.config.maxProxyCount) {
|
|
110
|
+
maxIpsCount = this.app.config.maxProxyCount + 1;
|
|
111
|
+
}
|
|
98
112
|
|
|
99
113
|
if (maxIpsCount > 0) {
|
|
100
114
|
// if maxIpsCount present, only keep `maxIpsCount` ips
|
|
101
115
|
// [ illegalIp, clientRealIp, proxyIp1, proxyIp2 ...]
|
|
102
|
-
this[IPS] =
|
|
116
|
+
this[IPS] = ips = ips.slice(-maxIpsCount);
|
|
103
117
|
}
|
|
104
|
-
return
|
|
105
|
-
}
|
|
118
|
+
return ips;
|
|
119
|
+
}
|
|
106
120
|
|
|
107
121
|
/**
|
|
108
122
|
* Get the request remote IPv4 address
|
|
@@ -115,16 +129,16 @@ module.exports = {
|
|
|
115
129
|
* => '111.10.2.1'
|
|
116
130
|
* ```
|
|
117
131
|
*/
|
|
118
|
-
get ip() {
|
|
132
|
+
get ip(): string {
|
|
119
133
|
if (this._ip) {
|
|
120
134
|
return this._ip;
|
|
121
135
|
}
|
|
122
|
-
const ip = this.ips[0]
|
|
136
|
+
const ip = this.ips[0] ?? this.socket.remoteAddress;
|
|
123
137
|
// will be '::ffff:x.x.x.x', should convert to standard IPv4 format
|
|
124
138
|
// https://zh.wikipedia.org/wiki/IPv6
|
|
125
|
-
this._ip = ip && ip.
|
|
139
|
+
this._ip = ip && ip.startsWith('::ffff:') ? ip.substring(7) : ip;
|
|
126
140
|
return this._ip;
|
|
127
|
-
}
|
|
141
|
+
}
|
|
128
142
|
|
|
129
143
|
/**
|
|
130
144
|
* Set the request remote IPv4 address
|
|
@@ -137,9 +151,9 @@ module.exports = {
|
|
|
137
151
|
* => '111.10.2.1'
|
|
138
152
|
* ```
|
|
139
153
|
*/
|
|
140
|
-
set ip(ip) {
|
|
154
|
+
set ip(ip: string) {
|
|
141
155
|
this._ip = ip;
|
|
142
|
-
}
|
|
156
|
+
}
|
|
143
157
|
|
|
144
158
|
/**
|
|
145
159
|
* detect if response should be json
|
|
@@ -150,25 +164,25 @@ module.exports = {
|
|
|
150
164
|
* @member {Boolean} Request#acceptJSON
|
|
151
165
|
* @since 1.0.0
|
|
152
166
|
*/
|
|
153
|
-
get acceptJSON() {
|
|
167
|
+
get acceptJSON(): boolean {
|
|
154
168
|
if (this.path.endsWith('.json')) return true;
|
|
155
169
|
if (this.response.type && this.response.type.indexOf('json') >= 0) return true;
|
|
156
170
|
if (this.accepts('html', 'text', 'json') === 'json') return true;
|
|
157
171
|
return false;
|
|
158
|
-
}
|
|
172
|
+
}
|
|
159
173
|
|
|
160
174
|
// How to read query safely
|
|
161
175
|
// https://github.com/koajs/qs/issues/5
|
|
162
|
-
_customQuery(cacheName, filter) {
|
|
176
|
+
_customQuery(cacheName: symbol, filter: (value: string | string[]) => string | string[]) {
|
|
163
177
|
const str = this.querystring || '';
|
|
164
|
-
let c = this[cacheName]
|
|
178
|
+
let c = this[cacheName] as Record<string, Record<string, string | string[]>>;
|
|
165
179
|
if (!c) {
|
|
166
180
|
c = this[cacheName] = {};
|
|
167
181
|
}
|
|
168
182
|
let cacheQuery = c[str];
|
|
169
183
|
if (!cacheQuery) {
|
|
170
184
|
cacheQuery = c[str] = {};
|
|
171
|
-
const isQueries = cacheName ===
|
|
185
|
+
const isQueries = cacheName === QUERIES_CACHE;
|
|
172
186
|
// `querystring.parse` CANNOT parse something like `a[foo]=1&a[bar]=2`
|
|
173
187
|
const query = str ? querystring.parse(str) : {};
|
|
174
188
|
for (const key in query) {
|
|
@@ -176,20 +190,19 @@ module.exports = {
|
|
|
176
190
|
// key is '', like `a=b&`
|
|
177
191
|
continue;
|
|
178
192
|
}
|
|
179
|
-
const value = filter(query[key]);
|
|
193
|
+
const value = filter(query[key]!);
|
|
180
194
|
cacheQuery[key] = value;
|
|
181
195
|
if (isQueries && RE_ARRAY_KEY.test(key)) {
|
|
182
196
|
// `this.queries['key'] => this.queries['key[]']` is compatibly supported
|
|
183
|
-
const
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
cacheQuery[subkey] = value;
|
|
197
|
+
const subKey = key.substring(0, key.length - 2);
|
|
198
|
+
if (!cacheQuery[subKey]) {
|
|
199
|
+
cacheQuery[subKey] = value;
|
|
187
200
|
}
|
|
188
201
|
}
|
|
189
202
|
}
|
|
190
203
|
}
|
|
191
204
|
return cacheQuery;
|
|
192
|
-
}
|
|
205
|
+
}
|
|
193
206
|
|
|
194
207
|
/**
|
|
195
208
|
* get params pass by querystring, all values are of string type.
|
|
@@ -212,8 +225,8 @@ module.exports = {
|
|
|
212
225
|
* ```
|
|
213
226
|
*/
|
|
214
227
|
get query() {
|
|
215
|
-
return this._customQuery(
|
|
216
|
-
}
|
|
228
|
+
return this._customQuery(QUERY_CACHE, firstValue) as Record<string, string>;
|
|
229
|
+
}
|
|
217
230
|
|
|
218
231
|
/**
|
|
219
232
|
* get params pass by querystring, all value are Array type. {@link Request#query}
|
|
@@ -232,50 +245,39 @@ module.exports = {
|
|
|
232
245
|
* ```
|
|
233
246
|
*/
|
|
234
247
|
get queries() {
|
|
235
|
-
return this._customQuery(
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
get accept() {
|
|
239
|
-
let accept = this[ACCEPTS];
|
|
240
|
-
if (accept) {
|
|
241
|
-
return accept;
|
|
242
|
-
}
|
|
243
|
-
accept = this[ACCEPTS] = accepts(this.req);
|
|
244
|
-
return accept;
|
|
245
|
-
},
|
|
248
|
+
return this._customQuery(QUERIES_CACHE, arrayValue) as Record<string, string[]>;
|
|
249
|
+
}
|
|
246
250
|
|
|
247
251
|
/**
|
|
248
252
|
* Set query-string as an object.
|
|
249
253
|
*
|
|
250
254
|
* @function Request#query
|
|
251
255
|
* @param {Object} obj set querystring and query object for request.
|
|
252
|
-
* @return {void}
|
|
253
256
|
*/
|
|
254
|
-
set query(obj) {
|
|
257
|
+
set query(obj: Record<string, string>) {
|
|
255
258
|
this.querystring = querystring.stringify(obj);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
+
}
|
|
260
|
+
}
|
|
259
261
|
|
|
260
|
-
function firstValue(value) {
|
|
262
|
+
function firstValue(value: string | string[]) {
|
|
261
263
|
if (Array.isArray(value)) {
|
|
262
264
|
value = value[0];
|
|
263
265
|
}
|
|
264
266
|
return value;
|
|
265
267
|
}
|
|
266
268
|
|
|
267
|
-
function arrayValue(value) {
|
|
269
|
+
function arrayValue(value: string | string[]) {
|
|
268
270
|
if (!Array.isArray(value)) {
|
|
269
271
|
value = [ value ];
|
|
270
272
|
}
|
|
271
273
|
return value;
|
|
272
274
|
}
|
|
273
275
|
|
|
274
|
-
function getFromHeaders(
|
|
276
|
+
function getFromHeaders(request: Request, names: string) {
|
|
275
277
|
if (!names) return '';
|
|
276
|
-
|
|
277
|
-
for (const name of
|
|
278
|
-
const value =
|
|
278
|
+
const fields = names.split(/\s*,\s*/);
|
|
279
|
+
for (const name of fields) {
|
|
280
|
+
const value = request.get<string>(name);
|
|
279
281
|
if (value) return value;
|
|
280
282
|
}
|
|
281
283
|
return '';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { Response as KoaResponse } from '@eggjs/core';
|
|
2
|
+
|
|
3
|
+
const REAL_STATUS = Symbol('response realStatus');
|
|
4
|
+
|
|
5
|
+
export default class Response extends KoaResponse {
|
|
6
|
+
/**
|
|
7
|
+
* Get or set a real status code.
|
|
8
|
+
*
|
|
9
|
+
* e.g.: Using 302 status redirect to the global error page
|
|
10
|
+
* instead of show current 500 status page.
|
|
11
|
+
* And access log should save 500 not 302,
|
|
12
|
+
* then the `realStatus` can help us find out the real status code.
|
|
13
|
+
* @member {Number} Response#realStatus
|
|
14
|
+
* @return {Number} The status code to be set.
|
|
15
|
+
*/
|
|
16
|
+
get realStatus(): number {
|
|
17
|
+
if (this[REAL_STATUS]) {
|
|
18
|
+
return this[REAL_STATUS] as number;
|
|
19
|
+
}
|
|
20
|
+
return this.status;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Set a real status code.
|
|
25
|
+
*
|
|
26
|
+
* e.g.: Using 302 status redirect to the global error page
|
|
27
|
+
* instead of show current 500 status page.
|
|
28
|
+
* And access log should save 500 not 302,
|
|
29
|
+
* then the `realStatus` can help us find out the real status code.
|
|
30
|
+
* @member {Number} Response#realStatus
|
|
31
|
+
* @param {Number} status The status code to be set.
|
|
32
|
+
*/
|
|
33
|
+
set realStatus(status: number) {
|
|
34
|
+
this[REAL_STATUS] = status;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -2,12 +2,19 @@
|
|
|
2
2
|
* meta middleware, should be the first middleware
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
import { performance } from 'node:perf_hooks';
|
|
6
|
+
import type { ContextDelegation, Next } from '../../lib/egg.js';
|
|
6
7
|
|
|
7
|
-
|
|
8
|
-
|
|
8
|
+
export interface MetaMiddlewareOptions {
|
|
9
|
+
enable: boolean;
|
|
10
|
+
logging: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export default (options: MetaMiddlewareOptions) => {
|
|
14
|
+
return async function meta(ctx: ContextDelegation, next: Next) {
|
|
9
15
|
if (options.logging) {
|
|
10
|
-
ctx.coreLogger.info('[meta] request started, host: %s, user-agent: %s',
|
|
16
|
+
ctx.coreLogger.info('[meta] request started, host: %s, user-agent: %s',
|
|
17
|
+
ctx.host, ctx.header['user-agent']);
|
|
11
18
|
}
|
|
12
19
|
await next();
|
|
13
20
|
// total response time header
|
|
@@ -1,7 +1,12 @@
|
|
|
1
|
-
|
|
1
|
+
import type { Next, ContextDelegation } from '../../lib/egg.js';
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
3
|
+
export interface NotFoundMiddlewareOptions {
|
|
4
|
+
enable: boolean;
|
|
5
|
+
pageUrl: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default (options: NotFoundMiddlewareOptions) => {
|
|
9
|
+
return async function notfound(ctx: ContextDelegation, next: Next) {
|
|
5
10
|
await next();
|
|
6
11
|
|
|
7
12
|
if (ctx.status !== 404 || ctx.body) {
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileURLToPath } from 'node:url';
|
|
3
|
+
import { readFile } from 'node:fs/promises';
|
|
4
|
+
import type { Next, ContextDelegation } from '../../lib/egg.js';
|
|
5
|
+
|
|
6
|
+
export type SiteFileContentFun = (ctx: ContextDelegation) => Promise<Buffer | string>;
|
|
7
|
+
|
|
8
|
+
export interface SiteFileMiddlewareOptions {
|
|
9
|
+
enable: boolean;
|
|
10
|
+
cacheControl: string;
|
|
11
|
+
[key: string]: string | Buffer | boolean | SiteFileContentFun | URL;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
const BUFFER_CACHE = Symbol('siteFile URL buffer cache');
|
|
15
|
+
|
|
16
|
+
export default (options: SiteFileMiddlewareOptions) => {
|
|
17
|
+
return async function siteFile(ctx: ContextDelegation, next: Next) {
|
|
18
|
+
if (ctx.method !== 'HEAD' && ctx.method !== 'GET') {
|
|
19
|
+
return next();
|
|
20
|
+
}
|
|
21
|
+
if (ctx.path[0] !== '/') {
|
|
22
|
+
return next();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
let content = options[ctx.path];
|
|
26
|
+
if (!content) {
|
|
27
|
+
return next();
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// '/favicon.ico': 'https://eggjs.org/favicon.ico' or '/favicon.ico': async (ctx) => 'https://eggjs.org/favicon.ico'
|
|
31
|
+
// content is function
|
|
32
|
+
if (typeof content === 'function') {
|
|
33
|
+
content = await content(ctx);
|
|
34
|
+
}
|
|
35
|
+
// content is url
|
|
36
|
+
if (typeof content === 'string') {
|
|
37
|
+
return ctx.redirect(content);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// URL
|
|
41
|
+
if (content instanceof URL) {
|
|
42
|
+
if (content.protocol !== 'file:') {
|
|
43
|
+
return ctx.redirect(content.href);
|
|
44
|
+
}
|
|
45
|
+
// protocol = file:
|
|
46
|
+
let buffer = Reflect.get(content, BUFFER_CACHE) as Buffer;
|
|
47
|
+
if (!buffer) {
|
|
48
|
+
buffer = await readFile(fileURLToPath(content));
|
|
49
|
+
Reflect.set(content, BUFFER_CACHE, buffer);
|
|
50
|
+
}
|
|
51
|
+
ctx.set('cache-control', options.cacheControl);
|
|
52
|
+
ctx.body = content;
|
|
53
|
+
ctx.type = path.extname(ctx.path);
|
|
54
|
+
return;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
// '/robots.txt': Buffer <xx..
|
|
58
|
+
// content is buffer
|
|
59
|
+
if (Buffer.isBuffer(content)) {
|
|
60
|
+
ctx.set('cache-control', options.cacheControl);
|
|
61
|
+
ctx.body = content;
|
|
62
|
+
ctx.type = path.extname(ctx.path);
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
return next();
|
|
67
|
+
};
|
|
68
|
+
};
|
|
@@ -1,18 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { pathToFileURL } from 'node:url';
|
|
3
|
+
import type { EggAppInfo } from '@eggjs/core';
|
|
4
|
+
import type { EggAppConfig } from '../lib/type.js';
|
|
5
|
+
import { getSourceFile } from '../lib/utils.js';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* The configuration of egg application, can be access by `app.config`
|
|
8
9
|
* @class Config
|
|
9
10
|
* @since 1.0.0
|
|
10
11
|
*/
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
const config = {
|
|
15
|
-
|
|
12
|
+
export default (appInfo: EggAppInfo) => {
|
|
13
|
+
const config: Partial<EggAppConfig> = {
|
|
16
14
|
/**
|
|
17
15
|
* The environment of egg
|
|
18
16
|
* @member {String} Config#env
|
|
@@ -131,7 +129,7 @@ module.exports = appInfo => {
|
|
|
131
129
|
HOME: appInfo.HOME,
|
|
132
130
|
|
|
133
131
|
/**
|
|
134
|
-
* The directory of server running. You can find `application_config.json` under it that is
|
|
132
|
+
* The directory of server running. You can find `application_config.json` under it that is dumped from `app.config`.
|
|
135
133
|
* @member {String} Config#rundir
|
|
136
134
|
* @default
|
|
137
135
|
* @since 1.0.0
|
|
@@ -153,7 +151,7 @@ module.exports = appInfo => {
|
|
|
153
151
|
/secret/i,
|
|
154
152
|
]),
|
|
155
153
|
timing: {
|
|
156
|
-
// if boot action >= slowBootActionMinDuration, egg core will print it to
|
|
154
|
+
// if boot action >= slowBootActionMinDuration, egg core will print it to warning log
|
|
157
155
|
slowBootActionMinDuration: 5000,
|
|
158
156
|
},
|
|
159
157
|
},
|
|
@@ -176,7 +174,7 @@ module.exports = appInfo => {
|
|
|
176
174
|
};
|
|
177
175
|
|
|
178
176
|
/**
|
|
179
|
-
* The
|
|
177
|
+
* The options of `notfound` middleware
|
|
180
178
|
*
|
|
181
179
|
* It will return page or json depend on negotiation when 404,
|
|
182
180
|
* If pageUrl is set, it will redirect to the page.
|
|
@@ -185,13 +183,14 @@ module.exports = appInfo => {
|
|
|
185
183
|
* @property {String} pageUrl - the 404 page url
|
|
186
184
|
*/
|
|
187
185
|
config.notfound = {
|
|
186
|
+
enable: true,
|
|
188
187
|
pageUrl: '',
|
|
189
188
|
};
|
|
190
189
|
|
|
191
190
|
/**
|
|
192
191
|
* The option of `siteFile` middleware
|
|
193
192
|
*
|
|
194
|
-
* You can map some files using this options, it will response
|
|
193
|
+
* You can map some files using this options, it will response immediately when matching.
|
|
195
194
|
*
|
|
196
195
|
* @member {Object} Config#siteFile - key is path, and value is url or buffer.
|
|
197
196
|
* @property {String} cacheControl - files cache , default is public, max-age=2592000
|
|
@@ -202,13 +201,14 @@ module.exports = appInfo => {
|
|
|
202
201
|
* };
|
|
203
202
|
*/
|
|
204
203
|
config.siteFile = {
|
|
205
|
-
|
|
204
|
+
enable: true,
|
|
205
|
+
'/favicon.ico': pathToFileURL(getSourceFile('config/favicon.png')),
|
|
206
206
|
// default cache in 30 days
|
|
207
207
|
cacheControl: 'public, max-age=2592000',
|
|
208
208
|
};
|
|
209
209
|
|
|
210
210
|
/**
|
|
211
|
-
* The
|
|
211
|
+
* The options of `bodyParser` middleware
|
|
212
212
|
*
|
|
213
213
|
* @member Config#bodyParser
|
|
214
214
|
* @property {Boolean} enable - enable bodyParser or not, default is true
|
|
@@ -236,8 +236,9 @@ module.exports = appInfo => {
|
|
|
236
236
|
depth: 5,
|
|
237
237
|
parameterLimit: 1000,
|
|
238
238
|
},
|
|
239
|
+
onProtoPoisoning: 'error',
|
|
239
240
|
onerror(err, ctx) {
|
|
240
|
-
err.message
|
|
241
|
+
err.message = `${err.message}, check bodyParser config`;
|
|
241
242
|
if (ctx.status === 404) {
|
|
242
243
|
// set default status to 400, meaning client bad request
|
|
243
244
|
ctx.status = 400;
|
|
@@ -264,8 +265,7 @@ module.exports = appInfo => {
|
|
|
264
265
|
* @property {String} agentLogName - file name of agent worker log
|
|
265
266
|
* @property {Object} coreLogger - custom config of coreLogger
|
|
266
267
|
* @property {Boolean} allowDebugAtProd - allow debug log at prod, defaults to false
|
|
267
|
-
* @property {Boolean}
|
|
268
|
-
* @property {Boolean} enableFastContextLogger - using the app logger instead of EggContextLogger, defaults to false
|
|
268
|
+
* @property {Boolean} enableFastContextLogger - using the app logger instead of EggContextLogger, defaults to true
|
|
269
269
|
*/
|
|
270
270
|
config.logger = {
|
|
271
271
|
dir: path.join(appInfo.root, 'logs', appInfo.name),
|
|
@@ -282,8 +282,7 @@ module.exports = appInfo => {
|
|
|
282
282
|
errorLogName: 'common-error.log',
|
|
283
283
|
coreLogger: {},
|
|
284
284
|
allowDebugAtProd: false,
|
|
285
|
-
|
|
286
|
-
enableFastContextLogger: false,
|
|
285
|
+
enableFastContextLogger: true,
|
|
287
286
|
};
|
|
288
287
|
|
|
289
288
|
/**
|
|
@@ -303,39 +302,20 @@ module.exports = appInfo => {
|
|
|
303
302
|
* @property {Number} httpsAgent.freeSocketTimeout - httpss agent socket keepalive max free time, default is 4000 ms.
|
|
304
303
|
* @property {Number} httpsAgent.maxSockets - https agent max socket number of one host, default is `Number.MAX_SAFE_INTEGER` @ses https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/MAX_SAFE_INTEGER
|
|
305
304
|
* @property {Number} httpsAgent.maxFreeSockets - https agent max free socket number of one host, default is 256.
|
|
306
|
-
* @property {Boolean} useHttpClientNext - use urllib@3 HttpClient
|
|
307
|
-
* @property {Boolean} allowH2 - use urllib@4 HttpClient and enable H2, default is false. Only works on Node.js >= 18
|
|
305
|
+
* @property {Boolean} useHttpClientNext - use urllib@3 HttpClient
|
|
308
306
|
*/
|
|
309
307
|
config.httpclient = {
|
|
310
|
-
enableDNSCache: false,
|
|
311
|
-
dnsCacheLookupInterval: 10000,
|
|
312
|
-
dnsCacheMaxLength: 1000,
|
|
313
|
-
|
|
314
308
|
request: {
|
|
315
309
|
timeout: 5000,
|
|
316
310
|
},
|
|
317
|
-
httpAgent: {
|
|
318
|
-
keepAlive: true,
|
|
319
|
-
freeSocketTimeout: 4000,
|
|
320
|
-
maxSockets: Number.MAX_SAFE_INTEGER,
|
|
321
|
-
maxFreeSockets: 256,
|
|
322
|
-
},
|
|
323
|
-
httpsAgent: {
|
|
324
|
-
keepAlive: true,
|
|
325
|
-
freeSocketTimeout: 4000,
|
|
326
|
-
maxSockets: Number.MAX_SAFE_INTEGER,
|
|
327
|
-
maxFreeSockets: 256,
|
|
328
|
-
},
|
|
329
|
-
useHttpClientNext: false,
|
|
330
|
-
// allowH2: false,
|
|
331
311
|
};
|
|
332
312
|
|
|
333
313
|
/**
|
|
334
|
-
* The
|
|
314
|
+
* The options of `meta` middleware
|
|
335
315
|
*
|
|
336
316
|
* @member Config#meta
|
|
337
|
-
* @property {Boolean} enable - enable meta or not, default is true
|
|
338
|
-
* @property {Boolean} logging - enable logging start request, default is false
|
|
317
|
+
* @property {Boolean} enable - enable meta or not, default is `true`
|
|
318
|
+
* @property {Boolean} logging - enable logging start request, default is `false`
|
|
339
319
|
*/
|
|
340
320
|
config.meta = {
|
|
341
321
|
enable: true,
|
|
@@ -371,7 +351,7 @@ module.exports = appInfo => {
|
|
|
371
351
|
config.serverTimeout = null;
|
|
372
352
|
|
|
373
353
|
/**
|
|
374
|
-
*
|
|
354
|
+
* The options of cluster
|
|
375
355
|
* @member {Object} Config#cluster
|
|
376
356
|
* @property {Object} listen - listen options, see {@link https://nodejs.org/api/http.html#http_server_listen_port_hostname_backlog_callback}
|
|
377
357
|
* @property {String} listen.path - set a unix sock path when server listen
|
|
@@ -418,7 +398,7 @@ module.exports = appInfo => {
|
|
|
418
398
|
* };
|
|
419
399
|
* }
|
|
420
400
|
*/
|
|
421
|
-
config.onClientError =
|
|
401
|
+
config.onClientError = undefined;
|
|
422
402
|
|
|
423
403
|
return config;
|
|
424
404
|
};
|
|
Binary file
|