topbit 2.0.0 → 3.0.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.cn.md +133 -176
- package/README.md +803 -592
- package/bin/new-ctl.js +7 -3
- package/demo/allow.js +13 -13
- package/demo/controller/api.js +15 -0
- package/demo/extends.js +5 -0
- package/demo/http2.js +34 -0
- package/demo/http2_proxy_backend.js +45 -0
- package/demo/http2proxy.js +48 -0
- package/demo/http_proxy_backend.js +44 -0
- package/demo/httpproxy.js +47 -0
- package/demo/loader.js +27 -0
- package/demo/log.js +1 -1
- package/demo/memlimit.js +1 -1
- package/demo/min.js +1 -1
- package/demo/serv.js +1 -1
- package/images/topbit-middleware.png +0 -0
- package/images/topbit.png +0 -0
- package/package.json +7 -6
- package/src/_loadExtends.js +21 -0
- package/src/bodyparser.js +1 -1
- package/src/context1.js +19 -19
- package/src/context2.js +11 -8
- package/src/ctxpool.js +1 -0
- package/src/extends/Http2Pool.js +365 -0
- package/src/extends/__randstring.js +24 -0
- package/src/extends/cookie.js +44 -0
- package/src/extends/cors.js +334 -0
- package/src/extends/errorlog.js +252 -0
- package/src/extends/http2limit.js +126 -0
- package/src/extends/http2proxy.js +691 -0
- package/src/extends/jwt.js +217 -0
- package/src/extends/mixlogger.js +63 -0
- package/src/extends/paramcheck.js +266 -0
- package/src/extends/proxy.js +662 -0
- package/src/extends/realip.js +34 -0
- package/src/extends/referer.js +68 -0
- package/src/extends/resource.js +398 -0
- package/src/extends/session.js +174 -0
- package/src/extends/setfinal.js +50 -0
- package/src/extends/sni.js +48 -0
- package/src/extends/sse.js +293 -0
- package/src/extends/timing.js +111 -0
- package/src/extends/tofile.js +123 -0
- package/src/http1.js +15 -16
- package/src/http2.js +5 -5
- package/src/httpc.js +3 -3
- package/src/lib/npargv.js +354 -0
- package/src/lib/zipdata.js +45 -0
- package/src/middleware1.js +15 -16
- package/src/middleware2.js +4 -9
- package/src/token/token.js +4 -5
- package/src/topbit.js +13 -11
- package/test/{test-helper.js → test-ext.js} +1 -1
- package/test/test-route.js +1 -1
- package/cache/allow.js +0 -130
- package/cache/errserv.js +0 -45
- package/cache/minserv.js +0 -167
- package/cache/router.js +0 -84
- package/cache/servsock.js +0 -286
- package/cache/sni.js +0 -66
- package/images/titbit-middleware.png +0 -0
- package/images/titbit.png +0 -0
- package/tmp/buff-code +0 -134
- package/tmp/devplan +0 -9
- package/tmp/evt-test.js +0 -34
- package/tmp/fastParseUrl.js +0 -302
- package/tmp/router-rule.js +0 -559
- package/tmp/test-cdps.js +0 -122
- package/tmp/titbit.js +0 -1286
- /package/{cache/rsa → demo/cert}/localhost-cert.pem +0 -0
- /package/{cache/rsa → demo/cert}/localhost-privkey.pem +0 -0
|
@@ -0,0 +1,354 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* {
|
|
5
|
+
* '-a' : {
|
|
6
|
+
* name: 'a',
|
|
7
|
+
* type: 'number|string|int|float|bool',
|
|
8
|
+
* min: 0,
|
|
9
|
+
* max: 100,
|
|
10
|
+
* match: RegExp,
|
|
11
|
+
* default : any
|
|
12
|
+
* },
|
|
13
|
+
*
|
|
14
|
+
* '$2': {
|
|
15
|
+
*
|
|
16
|
+
* },
|
|
17
|
+
* {
|
|
18
|
+
* '--port=' : {
|
|
19
|
+
* name : 'port',
|
|
20
|
+
* type : 'int',
|
|
21
|
+
* min: 2000,
|
|
22
|
+
* max: 5000,
|
|
23
|
+
* default: 3456
|
|
24
|
+
* }
|
|
25
|
+
* }
|
|
26
|
+
* }
|
|
27
|
+
*
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
function setVal (a, ainfo, obj, next) {
|
|
31
|
+
|
|
32
|
+
if (ainfo.type && ['int', 'float', 'number'].indexOf(ainfo.type) >= 0) {
|
|
33
|
+
if (isNaN(next)) {
|
|
34
|
+
return {
|
|
35
|
+
ok: false,
|
|
36
|
+
message: `${a} 类型错误,要求参数必须是数字类型:${next}`
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (ainfo.type === 'int' || ainfo.type === 'number') {
|
|
41
|
+
next = parseInt(next)
|
|
42
|
+
} else {
|
|
43
|
+
next = parseFloat(next)
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (ainfo.min !== undefined) {
|
|
48
|
+
if (next < ainfo.min) {
|
|
49
|
+
return {
|
|
50
|
+
ok: false,
|
|
51
|
+
message: `${a} 数值不能低于 ${ainfo.min}`
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
if (ainfo.max !== undefined) {
|
|
57
|
+
if (next > ainfo.max) {
|
|
58
|
+
return {
|
|
59
|
+
ok: false,
|
|
60
|
+
message: `${a} 数值不能大于 ${ainfo.max}`
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
if (ainfo.match && ainfo.match instanceof RegExp) {
|
|
66
|
+
if (!ainfo.match.test(next)) {
|
|
67
|
+
return {
|
|
68
|
+
ok: false,
|
|
69
|
+
message: `${a} 数值无法匹配 ${next}`
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
let val = next
|
|
75
|
+
|
|
76
|
+
if (ainfo.callback && typeof ainfo.callback === 'function') {
|
|
77
|
+
val = ainfo.callback(next)
|
|
78
|
+
if (val === undefined) val = next
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
obj[ ainfo.name || a ] = val
|
|
82
|
+
|
|
83
|
+
return {
|
|
84
|
+
ok: true,
|
|
85
|
+
message: ''
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
function checkAndSet (a, ainfo, obj, next) {
|
|
91
|
+
|
|
92
|
+
if (typeof ainfo === 'boolean') {
|
|
93
|
+
obj[a] = true
|
|
94
|
+
return {
|
|
95
|
+
ok: true,
|
|
96
|
+
message: '',
|
|
97
|
+
op: 'none'
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
if (ainfo.type === 'bool' || ainfo.type === 'boolean') {
|
|
102
|
+
obj[ ainfo.name || a ] = true
|
|
103
|
+
|
|
104
|
+
return {
|
|
105
|
+
ok: true,
|
|
106
|
+
message: '',
|
|
107
|
+
op: 'none'
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (next === null) {
|
|
112
|
+
return {
|
|
113
|
+
ok: false,
|
|
114
|
+
message: `${a} 必须携带参数。`
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
let r = setVal(a, ainfo, obj, next)
|
|
119
|
+
|
|
120
|
+
if (!r.ok && ainfo.default !== undefined) {
|
|
121
|
+
r.ok = true
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
if (r.ok) {
|
|
125
|
+
r.op = 'next'
|
|
126
|
+
|
|
127
|
+
if (a[a.length - 1] === '=') {
|
|
128
|
+
r.op = 'none'
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
return r
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
function setAutoDefault (opts, k) {
|
|
136
|
+
switch (opts[k].type) {
|
|
137
|
+
case 'number':
|
|
138
|
+
case 'int':
|
|
139
|
+
case 'float':
|
|
140
|
+
opts[k].default = 0
|
|
141
|
+
if (opts[k].min)
|
|
142
|
+
opts[k].default = opts[k].min;
|
|
143
|
+
break
|
|
144
|
+
|
|
145
|
+
case 'string':
|
|
146
|
+
opts[k].default = ''
|
|
147
|
+
break
|
|
148
|
+
|
|
149
|
+
case 'bool':
|
|
150
|
+
case 'boolean':
|
|
151
|
+
opts[k].default = false
|
|
152
|
+
break
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/*
|
|
157
|
+
* opts['@autoDefault'] = true 表示自动设定默认值
|
|
158
|
+
*
|
|
159
|
+
* */
|
|
160
|
+
|
|
161
|
+
function parseArgv (options = null, obj = null) {
|
|
162
|
+
if (!options) options = {}
|
|
163
|
+
|
|
164
|
+
if (obj === null) obj = {}
|
|
165
|
+
|
|
166
|
+
let opts = {}
|
|
167
|
+
|
|
168
|
+
for (let k in options) {
|
|
169
|
+
opts[k] = options[k]
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
let autoDefault = false
|
|
173
|
+
|
|
174
|
+
if (opts['@autoDefault'] === undefined) opts['@autoDefault'] = true;
|
|
175
|
+
|
|
176
|
+
if (opts['@autoDefault'] !== undefined) {
|
|
177
|
+
autoDefault = !!opts['@autoDefault']
|
|
178
|
+
delete opts['@autoDefault']
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
let commands = []
|
|
182
|
+
if (opts['@command'] !== undefined) {
|
|
183
|
+
if (typeof opts['@command'] === 'string') {
|
|
184
|
+
opts['@command'].split(' ').filter(p => p.length > 0).forEach(a => {
|
|
185
|
+
commands.push(a.trim())
|
|
186
|
+
})
|
|
187
|
+
} else if (Array.isArray(opts['@command'])) {
|
|
188
|
+
commands = opts['@command'];
|
|
189
|
+
}
|
|
190
|
+
delete opts['@command'];
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
let defaultCommand = ''
|
|
194
|
+
if (opts['@defaultCommand'] !== undefined && commands.indexOf(opts['@defaultCommand']) >= 0) {
|
|
195
|
+
defaultCommand = opts['@defaultCommand'];
|
|
196
|
+
delete opts['@defaultCommand'];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
let userCommand = null
|
|
200
|
+
let commandFromInput = false
|
|
201
|
+
if (commands.length > 0) {
|
|
202
|
+
if (process.argv.length < 3) {
|
|
203
|
+
if (defaultCommand) userCommand = defaultCommand;
|
|
204
|
+
else {
|
|
205
|
+
return {
|
|
206
|
+
ok: false,
|
|
207
|
+
message: '请使用子命令:' + commands.join('|'),
|
|
208
|
+
args: obj
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
} else if (commands.indexOf(process.argv[2]) < 0) {
|
|
212
|
+
if (defaultCommand) userCommand = defaultCommand;
|
|
213
|
+
else {
|
|
214
|
+
return {
|
|
215
|
+
ok: false,
|
|
216
|
+
message: '不支持的子命令',
|
|
217
|
+
args: obj
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
} else {
|
|
221
|
+
commandFromInput = true
|
|
222
|
+
userCommand = process.argv[2]
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
let tmp_val
|
|
227
|
+
|
|
228
|
+
for (let k in opts) {
|
|
229
|
+
if (typeof opts[k] === 'string' && opts[k].trim().length > 0) {
|
|
230
|
+
opts[k] = {
|
|
231
|
+
name: opts[k].trim(),
|
|
232
|
+
type: 'boolean',
|
|
233
|
+
default: false
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
if (typeof opts[k] !== 'object' || opts[k].toString() !== '[object Object]') {
|
|
238
|
+
|
|
239
|
+
opts[k] = {
|
|
240
|
+
type : 'boolean',
|
|
241
|
+
name : k,
|
|
242
|
+
default: false
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
} else if (opts[k].type === undefined) {
|
|
246
|
+
|
|
247
|
+
if (k.indexOf('=') > 0) {
|
|
248
|
+
opts[k].type = 'string'
|
|
249
|
+
} else if (opts[k].match || opts[k].callback) {
|
|
250
|
+
opts[k].type = 'string'
|
|
251
|
+
} else {
|
|
252
|
+
if (opts[k].min !== undefined || opts[k].max !== undefined) {
|
|
253
|
+
opts[k].type = 'int'
|
|
254
|
+
} else if (opts[k].default !== undefined) {
|
|
255
|
+
tmp_val = typeof opts[k].default
|
|
256
|
+
if (tmp_val === 'number' || tmp_val === 'boolean' || tmp_val === 'string') {
|
|
257
|
+
opts[k].type = tmp_val
|
|
258
|
+
} else {
|
|
259
|
+
opts[k].type = 'string'
|
|
260
|
+
}
|
|
261
|
+
} else {
|
|
262
|
+
opts[k].type = 'bool'
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
autoDefault && opts[k].default === undefined && setAutoDefault(opts, k)
|
|
269
|
+
|
|
270
|
+
if (opts[k].type === 'bool' || opts[k].type === 'boolean') {
|
|
271
|
+
obj[ opts[k].name || k ] = false
|
|
272
|
+
} else if (opts[k].default !== undefined) {
|
|
273
|
+
obj[ opts[k].name || k ] = opts[k].default
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
for (let k in opts) {
|
|
279
|
+
if (opts[k].alias && typeof opts[k].alias === 'string' && opts[k].alias !== k) {
|
|
280
|
+
opts[opts[k].alias] = opts[k]
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
let a
|
|
285
|
+
let next
|
|
286
|
+
let next_end = process.argv.length - 1
|
|
287
|
+
let r = ''
|
|
288
|
+
let i = 2
|
|
289
|
+
let offset = 1
|
|
290
|
+
if (commands.length > 0 && commandFromInput) {
|
|
291
|
+
i++
|
|
292
|
+
offset = 2
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
let ind = 0
|
|
296
|
+
let pos_key = ''
|
|
297
|
+
let aList = []
|
|
298
|
+
|
|
299
|
+
while (i < process.argv.length) {
|
|
300
|
+
|
|
301
|
+
//先检测是否存在对位置的引用
|
|
302
|
+
pos_key = '$' + `${i-offset}`
|
|
303
|
+
if (opts[pos_key]) {
|
|
304
|
+
r = checkAndSet(pos_key, opts[pos_key], obj, process.argv[i])
|
|
305
|
+
if (!r.ok) {
|
|
306
|
+
r.args = obj
|
|
307
|
+
return r
|
|
308
|
+
}
|
|
309
|
+
i++
|
|
310
|
+
continue
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
a = process.argv[i]
|
|
314
|
+
|
|
315
|
+
next = i < next_end ? process.argv[i+1] : null
|
|
316
|
+
|
|
317
|
+
ind = a.indexOf('=')
|
|
318
|
+
|
|
319
|
+
if (ind > 0) {
|
|
320
|
+
a = a.substring(0, ind+1)
|
|
321
|
+
next = process.argv[i].substring(ind+1)
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
if (opts[a]) {
|
|
325
|
+
r = checkAndSet(a, opts[a], obj, next)
|
|
326
|
+
if (!r.ok) {
|
|
327
|
+
r.args = obj
|
|
328
|
+
return r
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
if (r.op === 'next') {
|
|
332
|
+
i += 2
|
|
333
|
+
continue
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
} else {
|
|
337
|
+
if (a[0] !== '-') {
|
|
338
|
+
a[0] !== '\\' ? aList.push(a) : aList.push(a.substring(1))
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
i++
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
return {
|
|
346
|
+
ok: true,
|
|
347
|
+
message: '',
|
|
348
|
+
args: obj,
|
|
349
|
+
list: aList,
|
|
350
|
+
command: userCommand
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
module.exports = parseArgv
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const zlib = require('zlib')
|
|
4
|
+
const fs = require('fs')
|
|
5
|
+
|
|
6
|
+
const fsp = fs.promises
|
|
7
|
+
|
|
8
|
+
let zipdata = async (pathfile, isData=false) => {
|
|
9
|
+
let d
|
|
10
|
+
|
|
11
|
+
if (isData) {
|
|
12
|
+
d = pathfile
|
|
13
|
+
} else {
|
|
14
|
+
d = await fsp.readFile(pathfile)
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return await new Promise((rv, rj) => {
|
|
18
|
+
zlib.gzip(d, (err, zipdata) => {
|
|
19
|
+
if (err) {
|
|
20
|
+
rj (err)
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
rv(zipdata)
|
|
24
|
+
})
|
|
25
|
+
})
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
zipdata.unzip = async (pathfile, isData = false) => {
|
|
29
|
+
let d
|
|
30
|
+
if (isData) {
|
|
31
|
+
d = pathfile
|
|
32
|
+
} else {
|
|
33
|
+
d = await fsp.readFile(pathfile)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return new Promise((rv, rj) => {
|
|
37
|
+
zlib.unzip(d, (err, data) => {
|
|
38
|
+
if (err) rj(err)
|
|
39
|
+
|
|
40
|
+
rv(data)
|
|
41
|
+
})
|
|
42
|
+
})
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
module.exports = zipdata
|
package/src/middleware1.js
CHANGED
|
@@ -16,18 +16,18 @@ class Middleware extends MidCore {
|
|
|
16
16
|
await this.exec(ctx, ctx.group);
|
|
17
17
|
} catch (err) {
|
|
18
18
|
|
|
19
|
-
this.errorHandle(err, '--ERR-
|
|
19
|
+
this.errorHandle(err, '--ERR-res--');
|
|
20
20
|
|
|
21
21
|
try {
|
|
22
|
-
if (ctx.
|
|
23
|
-
ctx.
|
|
24
|
-
ctx.
|
|
22
|
+
if (ctx.res && !ctx.res.writableEnded) {
|
|
23
|
+
ctx.res.statusCode = 500;
|
|
24
|
+
ctx.res.end();
|
|
25
25
|
}
|
|
26
26
|
} catch (err) {}
|
|
27
27
|
|
|
28
28
|
} finally {
|
|
29
|
-
ctx.
|
|
30
|
-
ctx.
|
|
29
|
+
ctx.req = null;
|
|
30
|
+
ctx.res = null;
|
|
31
31
|
ctx.data = null;
|
|
32
32
|
ctx.box = null;
|
|
33
33
|
ctx.service = null;
|
|
@@ -37,7 +37,6 @@ class Middleware extends MidCore {
|
|
|
37
37
|
ctx.rawBody = null;
|
|
38
38
|
ctx.files = null;
|
|
39
39
|
ctx.param = null;
|
|
40
|
-
ctx.reply = null;
|
|
41
40
|
ctx.user = null;
|
|
42
41
|
ctx = null;
|
|
43
42
|
}
|
|
@@ -51,9 +50,9 @@ class Middleware extends MidCore {
|
|
|
51
50
|
*/
|
|
52
51
|
addFinal() {
|
|
53
52
|
let fr = async (ctx, next) => {
|
|
54
|
-
await next();
|
|
53
|
+
await next(ctx);
|
|
55
54
|
|
|
56
|
-
if (!ctx.
|
|
55
|
+
if (!ctx.res || ctx.res.writableEnded || !ctx.res.writable || ctx.res.destroyed) {
|
|
57
56
|
return;
|
|
58
57
|
}
|
|
59
58
|
|
|
@@ -63,10 +62,10 @@ class Middleware extends MidCore {
|
|
|
63
62
|
let content_type = 'text/plain;charset=utf-8';
|
|
64
63
|
let datatype = typeof ctx.data;
|
|
65
64
|
|
|
66
|
-
if (!(ctx.
|
|
65
|
+
if (!(ctx.res.headersSent || ctx.res.hasHeader('content-type')) )
|
|
67
66
|
{
|
|
68
67
|
if (datatype === 'object') {
|
|
69
|
-
ctx.
|
|
68
|
+
ctx.res.setHeader('content-type','application/json;charset=utf-8');
|
|
70
69
|
}
|
|
71
70
|
else if (datatype === 'string' && ctx.data.length > 1) {
|
|
72
71
|
switch (ctx.data[0]) {
|
|
@@ -80,18 +79,18 @@ class Middleware extends MidCore {
|
|
|
80
79
|
break;
|
|
81
80
|
default:;
|
|
82
81
|
}
|
|
83
|
-
ctx.
|
|
82
|
+
ctx.res.setHeader('content-type', content_type);
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
|
|
87
86
|
if (!ctx.data) {
|
|
88
|
-
ctx.
|
|
87
|
+
ctx.res.end()
|
|
89
88
|
} else if (ctx.data instanceof Buffer || datatype === 'string') {
|
|
90
|
-
ctx.
|
|
89
|
+
ctx.res.end(ctx.data, ctx.dataEncoding)
|
|
91
90
|
} else if (datatype === 'number') {
|
|
92
|
-
ctx.
|
|
91
|
+
ctx.res.end(`${ctx.data}`)
|
|
93
92
|
} else {
|
|
94
|
-
ctx.
|
|
93
|
+
ctx.res.end(JSON.stringify(ctx.data))
|
|
95
94
|
}
|
|
96
95
|
|
|
97
96
|
}
|
package/src/middleware2.js
CHANGED
|
@@ -34,7 +34,8 @@ class Middleware extends MidCore {
|
|
|
34
34
|
ctx.data = null;
|
|
35
35
|
ctx.dataHeaders = null;
|
|
36
36
|
ctx.stream = null;
|
|
37
|
-
ctx.
|
|
37
|
+
ctx.req = null;
|
|
38
|
+
ctx.res = null;
|
|
38
39
|
ctx.service = null;
|
|
39
40
|
ctx.box = null;
|
|
40
41
|
ctx.requestCall = null;
|
|
@@ -43,7 +44,6 @@ class Middleware extends MidCore {
|
|
|
43
44
|
ctx.rawBody = null;
|
|
44
45
|
ctx.files = null;
|
|
45
46
|
ctx.param = null;
|
|
46
|
-
ctx.reply = null;
|
|
47
47
|
ctx.user = null;
|
|
48
48
|
ctx = null;
|
|
49
49
|
}
|
|
@@ -53,14 +53,9 @@ class Middleware extends MidCore {
|
|
|
53
53
|
/** 这是最终添加的请求中间件。基于洋葱模型,这个中间件最先执行,所以最后会返回响应结果。 */
|
|
54
54
|
addFinal() {
|
|
55
55
|
let fr = async (ctx, next) => {
|
|
56
|
-
|
|
57
|
-
await next();
|
|
56
|
+
await next(ctx);
|
|
58
57
|
|
|
59
|
-
if(!ctx.stream
|
|
60
|
-
|| ctx.stream.closed
|
|
61
|
-
|| ctx.stream.destroyed
|
|
62
|
-
|| !ctx.stream.writable)
|
|
63
|
-
{
|
|
58
|
+
if(!ctx.stream || ctx.stream.closed || ctx.stream.destroyed || !ctx.stream.writable) {
|
|
64
59
|
return ;
|
|
65
60
|
}
|
|
66
61
|
|
package/src/token/token.js
CHANGED
|
@@ -436,13 +436,13 @@ class TopbitToken {
|
|
|
436
436
|
let token = c.headers.authorization
|
|
437
437
|
|
|
438
438
|
if (!token) {
|
|
439
|
-
return c.status(self.failedCode).
|
|
439
|
+
return c.status(self.failedCode).to('!token')
|
|
440
440
|
}
|
|
441
441
|
|
|
442
|
-
let uinfo = self.
|
|
442
|
+
let uinfo = self.verifyAccessToken(token)
|
|
443
443
|
|
|
444
444
|
if (!uinfo.ok) {
|
|
445
|
-
return c.status(self.failedCode).
|
|
445
|
+
return c.status(self.failedCode).to(uinfo.errcode)
|
|
446
446
|
}
|
|
447
447
|
|
|
448
448
|
c.box.user = uinfo
|
|
@@ -452,11 +452,10 @@ class TopbitToken {
|
|
|
452
452
|
c.setHeader('x-refresh-token', new_token)
|
|
453
453
|
}
|
|
454
454
|
|
|
455
|
-
await next()
|
|
455
|
+
await next(c)
|
|
456
456
|
}
|
|
457
457
|
}
|
|
458
458
|
|
|
459
459
|
}
|
|
460
460
|
|
|
461
461
|
module.exports = TopbitToken
|
|
462
|
-
|
package/src/topbit.js
CHANGED
|
@@ -31,6 +31,9 @@ const Context2 = require('./context2.js');
|
|
|
31
31
|
const ext = require('./ext.js');
|
|
32
32
|
const TopbitLoader = require('./loader/loader.js')
|
|
33
33
|
const TopbitToken = require('./token/token.js')
|
|
34
|
+
const TopbitExtends = require('./_loadExtends.js')
|
|
35
|
+
const npargv = require('./lib/npargv.js')
|
|
36
|
+
const zipdata = require('./lib/zipdata.js')
|
|
34
37
|
|
|
35
38
|
let __instance__ = 0;
|
|
36
39
|
|
|
@@ -47,7 +50,7 @@ let _topbit_home_page = `<!DOCTYPE html><html>
|
|
|
47
50
|
<br>
|
|
48
51
|
<p>功能强大、简洁高效的Web开发框架。</p>
|
|
49
52
|
<p>文档 & 仓库:
|
|
50
|
-
<a style="text-decoration:none;color:#345689;" href="https://
|
|
53
|
+
<a style="text-decoration:none;color:#345689;" href="https://github.com/master-genius/topbit" target=_blank>
|
|
51
54
|
topbit</a></p>
|
|
52
55
|
</div>
|
|
53
56
|
</div>
|
|
@@ -213,7 +216,7 @@ class Topbit {
|
|
|
213
216
|
notFound : 'not found',
|
|
214
217
|
badRequest : 'bad request',
|
|
215
218
|
//展示负载信息,必须使用daemon接口
|
|
216
|
-
|
|
219
|
+
loadMonitor : true,
|
|
217
220
|
loadInfoType : 'text', // text | json | orgjson | --null
|
|
218
221
|
loadInfoFile : '',
|
|
219
222
|
|
|
@@ -234,7 +237,7 @@ class Topbit {
|
|
|
234
237
|
|
|
235
238
|
maxUrlLength: 1152,
|
|
236
239
|
|
|
237
|
-
maxpool :
|
|
240
|
+
maxpool : 8192,
|
|
238
241
|
|
|
239
242
|
//子进程汇报资源信息的定时器毫秒数。
|
|
240
243
|
monitorTimeSlice: 500,
|
|
@@ -266,7 +269,7 @@ class Topbit {
|
|
|
266
269
|
//-1表示使用timeout的设置。
|
|
267
270
|
streamTimeout: -1,
|
|
268
271
|
|
|
269
|
-
requestTimeout:
|
|
272
|
+
requestTimeout: 65_000,
|
|
270
273
|
|
|
271
274
|
maxLoadRate: 75
|
|
272
275
|
};
|
|
@@ -279,7 +282,7 @@ class Topbit {
|
|
|
279
282
|
deny_type : 's',
|
|
280
283
|
//每秒单个IP可以进行请求次数的上限,0表示不限制。
|
|
281
284
|
maxIPRequest : 0,
|
|
282
|
-
unitTime :
|
|
285
|
+
unitTime : 30_000,
|
|
283
286
|
maxIPCache : 10_0000,
|
|
284
287
|
allow : null,
|
|
285
288
|
allow_type : 's',
|
|
@@ -370,10 +373,6 @@ class Topbit {
|
|
|
370
373
|
break;
|
|
371
374
|
|
|
372
375
|
case 'loadMonitor':
|
|
373
|
-
this.config.showLoadInfo = !!options[k];
|
|
374
|
-
break;
|
|
375
|
-
|
|
376
|
-
case 'showLoadInfo':
|
|
377
376
|
case 'daemon':
|
|
378
377
|
case 'debug':
|
|
379
378
|
case 'globalLog':
|
|
@@ -580,7 +579,7 @@ class Topbit {
|
|
|
580
579
|
}
|
|
581
580
|
}
|
|
582
581
|
|
|
583
|
-
if (this.config.
|
|
582
|
+
if (this.config.loadMonitor) {
|
|
584
583
|
this.monitor = new Monitor({
|
|
585
584
|
config : this.config,
|
|
586
585
|
secure : this.secure,
|
|
@@ -1262,7 +1261,7 @@ class Topbit {
|
|
|
1262
1261
|
|
|
1263
1262
|
} else if (cluster.isWorker) {
|
|
1264
1263
|
|
|
1265
|
-
if (this.config.
|
|
1264
|
+
if (this.config.loadMonitor) {
|
|
1266
1265
|
this.monitor.workerSend();
|
|
1267
1266
|
}
|
|
1268
1267
|
|
|
@@ -1287,5 +1286,8 @@ class Topbit {
|
|
|
1287
1286
|
|
|
1288
1287
|
Topbit.Loader = TopbitLoader;
|
|
1289
1288
|
Topbit.Token = TopbitToken;
|
|
1289
|
+
Topbit.npargv = npargv;
|
|
1290
|
+
Topbit.zipdata = zipdata;
|
|
1291
|
+
Topbit.extensions = TopbitExtends;
|
|
1290
1292
|
|
|
1291
1293
|
module.exports = Topbit;
|
package/test/test-route.js
CHANGED