topbit 1.0.0 → 2.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.
Files changed (71) hide show
  1. package/LICENSE +128 -0
  2. package/README.cn.md +1562 -0
  3. package/README.md +1272 -0
  4. package/bin/app.js +17 -0
  5. package/bin/loadinfo.sh +18 -0
  6. package/bin/new-ctl.js +230 -0
  7. package/bin/newapp.js +22 -0
  8. package/cache/allow.js +130 -0
  9. package/cache/errserv.js +45 -0
  10. package/cache/minserv.js +167 -0
  11. package/cache/router.js +84 -0
  12. package/cache/rsa/localhost-cert.pem +19 -0
  13. package/cache/rsa/localhost-privkey.pem +28 -0
  14. package/cache/servsock.js +286 -0
  15. package/cache/sni.js +66 -0
  16. package/demo/allow.js +98 -0
  17. package/demo/group-api.js +161 -0
  18. package/demo/group-api2.js +109 -0
  19. package/demo/log.js +118 -0
  20. package/demo/memlimit.js +31 -0
  21. package/demo/min.js +7 -0
  22. package/demo/serv.js +15 -0
  23. package/images/middleware.jpg +0 -0
  24. package/images/titbit-middleware.png +0 -0
  25. package/images/titbit.png +0 -0
  26. package/package.json +38 -8
  27. package/src/bodyparser.js +420 -0
  28. package/src/connfilter.js +125 -0
  29. package/src/context1.js +166 -0
  30. package/src/context2.js +179 -0
  31. package/src/ctxpool.js +38 -0
  32. package/src/ext.js +318 -0
  33. package/src/fastParseUrl.js +426 -0
  34. package/src/headerLimit.js +18 -0
  35. package/src/http1.js +337 -0
  36. package/src/http2.js +337 -0
  37. package/src/httpc.js +251 -0
  38. package/src/loader/loader.js +999 -0
  39. package/src/logger.js +32 -0
  40. package/src/loggermsg.js +349 -0
  41. package/src/makeId.js +200 -0
  42. package/src/midcore.js +213 -0
  43. package/src/middleware1.js +104 -0
  44. package/src/middleware2.js +121 -0
  45. package/src/monitor.js +380 -0
  46. package/src/movefile.js +30 -0
  47. package/src/optionsCheck.js +54 -0
  48. package/src/randstring.js +23 -0
  49. package/src/router.js +682 -0
  50. package/src/sendmsg.js +27 -0
  51. package/src/strong.js +72 -0
  52. package/src/token/token.js +462 -0
  53. package/src/topbit.js +1291 -0
  54. package/src/versionCheck.js +31 -0
  55. package/test/test-bigctx.js +29 -0
  56. package/test/test-daemon-args.js +7 -0
  57. package/test/test-find.js +69 -0
  58. package/test/test-helper.js +81 -0
  59. package/test/test-route-sort.js +71 -0
  60. package/test/test-route.js +49 -0
  61. package/test/test-route2.js +51 -0
  62. package/test/test-run-args.js +7 -0
  63. package/test/test-url.js +52 -0
  64. package/tmp/buff-code +134 -0
  65. package/tmp/devplan +9 -0
  66. package/tmp/evt-test.js +34 -0
  67. package/tmp/fastParseUrl.js +302 -0
  68. package/tmp/router-rule.js +559 -0
  69. package/tmp/test-cdps.js +122 -0
  70. package/tmp/titbit.js +1286 -0
  71. package/main.js +0 -0
@@ -0,0 +1,31 @@
1
+ 'use strict'
2
+
3
+ const process = require('node:process')
4
+
5
+ /**
6
+ * 仅支持14.18以上版本。
7
+ */
8
+
9
+ let _err_info = '请使用Node.js v14.18 以上版本。(Please use Node.js v14.18+)'
10
+
11
+ module.exports = function (minVersion = 14) {
12
+ try {
13
+ let cur = parseInt(process.version.substring(1))
14
+
15
+ if (cur < minVersion) return {
16
+ stat: false,
17
+ errmsg: _err_info
18
+ }
19
+
20
+ return {
21
+ stat: true,
22
+ }
23
+
24
+ } catch (err) {
25
+ //不要因为小错误导致不能启动。
26
+ return {
27
+ stat: true,
28
+ errmsg: err.message
29
+ }
30
+ }
31
+ }
@@ -0,0 +1,29 @@
1
+ const titbit = require('../lib/titbit.js');
2
+
3
+ var app = new titbit({
4
+ debug: true,
5
+ //http2: true
6
+ });
7
+
8
+ var start_time = Date.now();
9
+
10
+ var ctx = null;
11
+
12
+ let total = 20000;
13
+
14
+ for (let i=0 ;i < total; i++) {
15
+ ctx = new app.httpServ.Context();
16
+ ctx.path = '/';
17
+ ctx.ip = '127.0.0.1';
18
+ ctx.requestCall = (c) => {
19
+ c.send('success');
20
+ };
21
+ ctx.box.rand = Math.random()
22
+ ctx = null;
23
+ }
24
+
25
+ var end_time = Date.now();
26
+
27
+ let rtm = end_time - start_time;
28
+
29
+ console.log(rtm, 'ms', `${parseInt(total * 1000 / rtm)}/s`);
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ const Titbit = require('../lib/titbit.js')
4
+
5
+ const app = new Titbit({debug: true})
6
+
7
+ app.daemon({port:3456, host: '127.0.0.1', worker: 2})
@@ -0,0 +1,69 @@
1
+ const doio = require('../lib/titbit.js');
2
+
3
+ const app = new doio();
4
+
5
+ try {
6
+ app.get('/:name/:', async c => {});
7
+ } catch (err) {
8
+ console.error(err.message);
9
+ }
10
+
11
+ try {
12
+ app.get('/:content/*', async c => {});
13
+ } catch (err) {
14
+ console.error(err.message);
15
+ }
16
+
17
+ try {
18
+ app.get('/x/*/y', async c => {});
19
+ } catch (err) {
20
+ console.error(err.message);
21
+ }
22
+
23
+ app.get('/p/:name/:id/:age/::', async c => {});
24
+
25
+ try {
26
+ console.log('测试 模式冲突 路由添加...')
27
+ app.get('/p/:x/:y/:z/:k', async c => {})
28
+ } catch (err) {}
29
+
30
+ app.get('/static/*', async c => {});
31
+
32
+ app.get('/file/download/*', async c => {});
33
+
34
+ app.get('/:sys/:release/iso/:handle', async c => {});
35
+
36
+ app.get('/xyz', async c => {});
37
+
38
+ app.get('/xyz/:key/oop/:oop', async c => {});
39
+ app.get('/xyz/:key/oo/:oop', async c => {});
40
+
41
+ try {
42
+ console.log('---测试非法路由字符串---')
43
+ app.get('/^*', async c => {})
44
+ } catch (err) {
45
+ console.log(err.message)
46
+ }
47
+
48
+ let test_arr = [
49
+ ['/p/wang/1/25/:', 'GET'],
50
+ ['/static/css/a.css', 'GET'],
51
+ ['/file/download/linux/ubuntu/20.04.iso', 'GET'],
52
+ ['/unix/freebsd/iso/download', 'GET'],
53
+ ['/:sys/:release/iso/:handle', 'GET'],
54
+ ['/:sys/:release/iso/:handle/a', 'GET'],
55
+ ['/xyz', 'GET'],
56
+ ['/xyz/1235/oop/oop', 'GET'],
57
+ ['/xyz/1235/oo/oop', 'GET']
58
+ ]
59
+
60
+ test_arr.forEach(a => {
61
+ console.log('find path:', a[0], a[1])
62
+ let r = app.router.findRealPath(a[0], a[1])
63
+ if (!r) {
64
+ console.log(' ----', 'not found\n')
65
+ } else {
66
+ console.log(' path:', r.key, ' args:', r.args, '\n')
67
+ }
68
+ })
69
+
@@ -0,0 +1,81 @@
1
+ 'use strict'
2
+
3
+ const helper = require('../lib/helper.js')
4
+
5
+ let key = '123456789012345678900987654321qw'
6
+
7
+ let data = JSON.stringify({
8
+ name : '简单的机械键盘',
9
+ age : 30
10
+ })
11
+
12
+ helper.aesIv = 'qwertyuiopasdfgh'
13
+
14
+ let cryptData = helper.aesEncrypt(data, key)
15
+
16
+ console.log('encrypt data:', cryptData)
17
+
18
+ console.log('aes decrypt: ', helper.aesDecrypt(cryptData, key))
19
+
20
+ helper.aesIv = '1010101010101010';
21
+
22
+ console.log('aesIv: ', helper.aesIv);
23
+
24
+ console.log('timestr: ', helper.timestr() )
25
+
26
+ console.log('make name: ', helper.makeName('aswe.jpg'))
27
+
28
+ console.log('make name: ', helper.makeName('qw123456..'))
29
+
30
+ console.log('make name: ', helper.makeName('qw123456.'))
31
+
32
+ console.log('make name: ', helper.makeName('qwert..jpe.zip'))
33
+
34
+ console.log(helper.ctype('.jppe'))
35
+
36
+ console.log(helper.ctype('.jpg'))
37
+
38
+ console.log(helper.ctype('.js'))
39
+
40
+ console.log('hmacsha1: ', helper.hmacsha1('12345', '123456', 'base64'))
41
+
42
+ console.log('sm3: ', helper.sm3(`${Date.now()}`))
43
+
44
+ for (let i = 0; i < 5; i++) {
45
+ console.log( helper.nrand(i, 1000 - i) )
46
+ }
47
+
48
+ for (let i = 0; i < 10 ; i++) {
49
+ console.log(helper.serialId(), helper.uuid() )
50
+ }
51
+
52
+ for (let i = 0; i < 10 ; i++) {
53
+ console.log( helper.uuid(true) )
54
+ }
55
+
56
+ let st = Date.now()
57
+
58
+ let uuidmap = {}
59
+ let tmp
60
+
61
+ let output_count = 0
62
+
63
+ let crashcount = 0
64
+
65
+ for (let i = 0; i < 1200000; i++) {
66
+ tmp = helper.uuid()
67
+ //tmp = helper.serialId(16)
68
+ if (uuidmap[tmp] === undefined) {
69
+ if (output_count < 10) {
70
+ console.log(tmp)
71
+ output_count += 1
72
+ }
73
+ uuidmap[tmp] = 1
74
+ } else {
75
+ crashcount += 1
76
+ }
77
+ }
78
+
79
+ let et = Date.now()
80
+
81
+ console.log(et - st, 'ms', crashcount)
@@ -0,0 +1,71 @@
1
+ const titbit = require('../lib/titbit');
2
+
3
+ let app = new titbit();
4
+
5
+ app.get(`/start/*`, async c => {
6
+ c.res.body = c.param;
7
+ });
8
+
9
+ app.get(`/:test/:o/:key/:z/:t`, async c => {
10
+ c.res.body = c.param;
11
+ });
12
+
13
+ app.get(`/test/:o/:key/:z/:t`, async c => {
14
+ c.res.body = c.param;
15
+ });
16
+
17
+ app.get(`/test/x/:key/:z/:t`, async c => {
18
+ c.res.body = c.param;
19
+ });
20
+
21
+ app.get(`/test/:o/:key/:z/:t/oo`, async c => {
22
+ c.res.body = c.param;
23
+ });
24
+
25
+ for(let i=0; i < 50; i++) {
26
+ app.get(`/test/${i}`, async c => {});
27
+
28
+ app.get(`/test/${i}/*`, async c => {
29
+ c.res.body = 'unix';
30
+ });
31
+
32
+ app.get(`/test/${i}-*`, async c => {});
33
+
34
+ app.get(`/test/x/${i}/:z/:t`, async c => {
35
+ c.res.body = i;
36
+ });
37
+
38
+ app.post(`/test/x/${i}/:z/:t`, async c => {
39
+ c.res.body = i;
40
+ });
41
+
42
+ app.get(`/test/linux/unix/${i}`, async c => {
43
+ c.res.body = 'unix';
44
+ });
45
+
46
+ app.get(`/test/${i}/x/y/*`, async c => {
47
+ c.res.body = `x y ${i}`;
48
+ });
49
+
50
+ }
51
+
52
+ app.router.argsRouteSort()
53
+
54
+ for (let m in app.router.argsRoute) {
55
+ console.log(m, '')
56
+ for (let a of app.router.argsRoute[m]) {
57
+ console.log(` ${a.path}`)
58
+ }
59
+ }
60
+
61
+ console.log(app.router.findRealPath('/test/35', 'GET'))
62
+
63
+ console.log(app.router.findRealPath('/test/x/49/x/y', 'GET'))
64
+
65
+ console.log(app.router.findRealPath('/test/35/a/s/d', 'GET'))
66
+
67
+ console.log(app.router.findRealPath('/test/35/x/y/w/e/r', 'GET'))
68
+
69
+ console.log(app.router.findRealPath('/test/35-*', 'GET'))
70
+
71
+ console.log(app.router.apiTable.GET['/test/x/1/:z/:t'])
@@ -0,0 +1,49 @@
1
+ const titbit = require('../lib/titbit.js');
2
+
3
+ var app = new titbit();
4
+
5
+ for(let i=0; i < 50; i++) {
6
+ app.get(`/test/x/${i}/:z/:t`, async c => {
7
+ c.res.body = i;
8
+ });
9
+
10
+ app.post(`/test/x/${i}/:z/:t`, async c => {
11
+ c.res.body = i;
12
+ });
13
+
14
+ app.get(`/test/linux/unix/${i}`, async c => {
15
+ c.res.body = 'unix';
16
+ });
17
+
18
+ app.get(`/test/${i}/*`, async c => {
19
+ c.res.body = 'unix';
20
+ });
21
+ }
22
+
23
+ let startTime = Date.now();
24
+
25
+ let t = '';
26
+ let count = 0;
27
+ for (let i=0; i < 60000; i++) {
28
+ if ( app.router.findRealPath('/test/x/49/qwe/sdfe', 'GET') ) {
29
+ count += 1;
30
+ }
31
+
32
+ if ( app.router.findRealPath('/test/49/qwe/dsv/ds/sd/asdff', 'GET') ) {
33
+ count += 1;
34
+ }
35
+
36
+ if ( app.router.findRealPath('/test/x/49/unix/freebsd', 'POST') ) {
37
+ count += 1;
38
+ }
39
+
40
+ if ( app.router.findRealPath('/test/linux/unix/49', 'GET') ) {
41
+ count += 1;
42
+ }
43
+ }
44
+
45
+ let endTime = Date.now();
46
+
47
+ console.log('timing', endTime - startTime, count);
48
+ console.log(parseInt(count / (endTime - startTime)) * 1000 );
49
+
@@ -0,0 +1,51 @@
1
+ const titbit = require('../lib/titbit.js');
2
+
3
+ var app = new titbit();
4
+
5
+ for(let i=0; i < 50; i++) {
6
+ app.get(`/test/:x/${i}/:z/:t`, async c => {
7
+ c.res.body = i;
8
+ });
9
+
10
+ app.post(`/test/:x/${i}/:z/:t`, async c => {
11
+ c.res.body = i;
12
+ });
13
+
14
+ app.get(`/test/:linux/:unix/${i}`, async c => {
15
+ c.res.body = 'unix';
16
+ }, '@linux-unix');
17
+
18
+ app.get(`/test/${i}/*`, async c => {
19
+ c.res.body = 'unix';
20
+ });
21
+ }
22
+
23
+ console.log('路由数量:', app.router.count);
24
+
25
+ let startTime = Date.now();
26
+
27
+ let t = '';
28
+ let count = 0;
29
+ for (let i=0; i < 60000; i++) {
30
+ if ( app.router.findRealPath('/test/x/49/qwe/sdfe', 'GET') ) {
31
+ count += 1;
32
+ }
33
+
34
+ if ( app.router.findRealPath('/test/49/qwe/dsv/ds/sd///////////asdff/', 'GET') ) {
35
+ count += 1;
36
+ }
37
+
38
+ if ( app.router.findRealPath('/test/x/49/unix//////freebsd/', 'POST') ) {
39
+ count += 1;
40
+ }
41
+
42
+ if ( app.router.findRealPath('/test/linux/unix/49/', 'GET') ) {
43
+ count += 1;
44
+ }
45
+ }
46
+
47
+ let endTime = Date.now();
48
+
49
+ console.log('timing', endTime - startTime, count);
50
+ console.log(parseInt(count / (endTime - startTime)) * 1000 );
51
+
@@ -0,0 +1,7 @@
1
+ 'use strict'
2
+
3
+ const Titbit = require('../lib/titbit.js')
4
+
5
+ const app = new Titbit({debug: true})
6
+
7
+ app.run({port:3456})
@@ -0,0 +1,52 @@
1
+ 'use strict'
2
+
3
+ const parseurl = require('../lib/fastParseUrl').fpurl
4
+ const url = require('url')
5
+
6
+ let tmp = ''
7
+ let urls = []
8
+
9
+ for (let i = 0 ; i < 20000; i++) {
10
+ tmp = `https://qw.e21e/x/y/z?name=hel${i+1}&a=${i}&a=${i*i+1}&age=${(i+1) % 35}&say=${encodeURIComponent('我是中国人')}`
11
+ + `&info=${encodeURIComponent('{"sign":"12dodfos9rhoaoz","x":"1=213"}')}`
12
+ + `&t=${encodeURIComponent('a=123&b=213')}&t=${encodeURIComponent('x=123&y=234')}&==&a=*&v=@&sdk&=123&we==`
13
+
14
+ for (let k=0; k < 10; k++) {
15
+ tmp += `&x=${encodeURIComponent('人民')}${k+1}%rr`
16
+ }
17
+
18
+ for (let k=0; k < 35; k++) {
19
+ tmp += `&xyz${k}=${encodeURIComponent('测试')}${k+1}`
20
+ }
21
+
22
+ for (let k = 0; k < 50; k ++) {
23
+ tmp += `&r=% ${k}`
24
+ }
25
+
26
+ tmp += '&op=123&qwe&&&===#a=123?234'
27
+
28
+ //tmp = `https://a.qwq/xyy/qwd/qwd?x=123&b=234&c=435#123few`
29
+ urls.push(tmp)
30
+ }
31
+
32
+ console.log(urls[0], '\n', urls[0].length)
33
+
34
+ let urlobj = []
35
+
36
+ let start_time = Date.now()
37
+
38
+ for (let i = 0; i < urls.length; i++) {
39
+ urlobj.push(parseurl(urls[i], true, false, 20))
40
+ //urlobj.push( new url.URL(urls[i], 'https://w3xm.cn') )
41
+ }
42
+
43
+ let end_time = Date.now()
44
+
45
+ console.log(`${urls.length}, ${end_time - start_time} ms`)
46
+
47
+ console.log(urlobj[0])
48
+ /*
49
+ for (let [k,v] of urlobj[0].searchParams) {
50
+ console.log(k, v)
51
+ }
52
+ */
package/tmp/buff-code ADDED
@@ -0,0 +1,134 @@
1
+ /* let code = 0
2
+ let isEncode = false
3
+ let encodeCheck = 0
4
+ let lastPos = 0
5
+ let pairStart = 0
6
+ let buf = ''
7
+ //let arr = []
8
+ let out = []
9
+ let seenSep = false
10
+
11
+ for (let i = 0; i < search.length; i++) {
12
+ code = search.charCodeAt(i)
13
+
14
+ if (code === CHAR_AMPERSAND) {
15
+ //arr.push(search.slice(lastPos, i))
16
+ //lastPos = i + 1
17
+ if (pairStart === i) {
18
+ //空的匹配,比如&&连续
19
+ lastPos = pairStart = i + 1
20
+ continue
21
+ }
22
+
23
+ if (lastPos < i)
24
+ buf += search.slice(lastPos, i)
25
+
26
+ if (isEncode) {
27
+ try {
28
+ buf = decodeURIComponent(buf)
29
+ } catch (err){
30
+
31
+ }
32
+ }
33
+
34
+ out.push(buf)
35
+
36
+ // If `buf` is the key, add an empty value.
37
+ !seenSep && out.push('')
38
+
39
+ seenSep = false
40
+ buf = ''
41
+ isEncode = false;
42
+ encodeCheck = 0
43
+ lastPos = pairStart = i + 1
44
+ continue
45
+ }
46
+
47
+ // Try matching key/value separator (e.g. '=') if we haven't already
48
+ if (!seenSep && code === CHAR_EQUAL) {
49
+ // Key/value separator match!
50
+ if (lastPos < i) buf += search.slice(lastPos, i)
51
+ if (isEncode) {
52
+ try {
53
+ buf = decodeURIComponent(buf)
54
+ } catch(err){}
55
+ }
56
+
57
+ out.push(buf)
58
+
59
+ seenSep = true
60
+ buf = ''
61
+ isEncode = false
62
+ encodeCheck = 0
63
+ lastPos = i + 1
64
+ continue
65
+ }
66
+
67
+ if (!isEncode) {
68
+ // Try to match an (valid) encoded byte (once) to minimize unnecessary
69
+ // calls to string decoding functions
70
+ if (code === CHAR_PERCENT) {
71
+ encodeCheck = 1
72
+ } else if (encodeCheck > 0) {
73
+ if (isHexTable[code] === 1) {
74
+ if (++encodeCheck === 3) {
75
+ isEncode = true
76
+ }
77
+ } else {
78
+ encodeCheck = 0
79
+ }
80
+ }
81
+ }
82
+
83
+
84
+ }
85
+
86
+ urlobj.query = out
87
+ return urlobj */
88
+
89
+ /*
90
+ let name_start = 0
91
+ let name_end = 0
92
+ let value_start = 0
93
+ let value_end = 0
94
+ let cur_name = ''
95
+ let query = urlobj.query
96
+
97
+ for (let i = 0; i < send; i++) {
98
+ switch (search[i]) {
99
+ case '=':
100
+ value_start = i + 1
101
+ name_end = i
102
+ cur_name = search.slice(name_start, name_end)
103
+ break
104
+
105
+ case '&':
106
+ value_end = i
107
+ name_start = i + 1
108
+ org_val = search.slice(value_start, value_end)
109
+
110
+ if (autoDecode && is_encoded(org_val)) {
111
+ try {
112
+ val = decodeURIComponent(org_val)
113
+ } catch (err) {
114
+ val = org_val
115
+ }
116
+ } else {
117
+ val = org_val
118
+ }
119
+
120
+ if (query[cur_name] === undefined || fastMode) {
121
+ query[cur_name] = val
122
+ } else {
123
+ if (!Array.isArray(query[cur_name])) {
124
+ query[cur_name] = [query[cur_name]]
125
+ }
126
+ query[cur_name].push(val)
127
+ }
128
+ break
129
+
130
+ }
131
+ }
132
+
133
+ return urlobj
134
+ */
package/tmp/devplan ADDED
@@ -0,0 +1,9 @@
1
+ context1.js sendHeader实现检测是否已经发送消息头并发送。
2
+
3
+ helper.uuid 实现部分自增序列。
4
+
5
+ helper 增加根据文件mime类型查找扩展名的函数。
6
+
7
+ helper 增加mime逆查找的函数。
8
+
9
+ context是否加入user项,默认为null。
@@ -0,0 +1,34 @@
1
+ 'use strict';
2
+
3
+ const titbit = require('../main')
4
+
5
+ const cluster = require('cluster')
6
+
7
+ const app = new titbit({
8
+ debug : true,
9
+ //loadInfoType: '--null',
10
+ loadMonitor: false,
11
+ })
12
+
13
+ app.setMsgEvent('testmsg', (w, msg) => {
14
+ console.log(w.id, msg)
15
+ w.send({
16
+ id: w.id,
17
+ rand: Math.random()
18
+ })
19
+ })
20
+
21
+ cluster.isWorker
22
+ &&
23
+ setInterval(() => {
24
+
25
+ app.send('testmsg', `${Date.now()}`)
26
+
27
+ }, 3000)
28
+
29
+ app.workerMsg((msg) => {
30
+ console.log(msg)
31
+ })
32
+
33
+ app.daemon(1235)
34
+