topbit 1.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/LICENSE +128 -0
- package/README.cn.md +1519 -0
- package/README.md +1483 -0
- package/bin/app.js +17 -0
- package/bin/loadinfo.sh +18 -0
- package/bin/new-ctl.js +234 -0
- package/bin/newapp.js +22 -0
- package/demo/allow.js +98 -0
- package/demo/cert/localhost-cert.pem +19 -0
- package/demo/cert/localhost-privkey.pem +28 -0
- package/demo/controller/api.js +15 -0
- package/demo/extends.js +5 -0
- package/demo/group-api.js +161 -0
- package/demo/group-api2.js +109 -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 +118 -0
- package/demo/memlimit.js +31 -0
- package/demo/min.js +7 -0
- package/demo/serv.js +15 -0
- package/images/middleware.jpg +0 -0
- package/images/topbit-middleware.png +0 -0
- package/images/topbit.png +0 -0
- package/package.json +42 -11
- package/src/_loadExtends.js +21 -0
- package/src/bodyparser.js +420 -0
- package/src/connfilter.js +125 -0
- package/src/context1.js +166 -0
- package/src/context2.js +182 -0
- package/src/ctxpool.js +39 -0
- package/src/ext.js +318 -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/fastParseUrl.js +426 -0
- package/src/headerLimit.js +18 -0
- package/src/http1.js +336 -0
- package/src/http2.js +337 -0
- package/src/httpc.js +251 -0
- package/src/lib/npargv.js +354 -0
- package/src/lib/zipdata.js +45 -0
- package/src/loader/loader.js +999 -0
- package/src/logger.js +32 -0
- package/src/loggermsg.js +349 -0
- package/src/makeId.js +200 -0
- package/src/midcore.js +213 -0
- package/src/middleware1.js +103 -0
- package/src/middleware2.js +116 -0
- package/src/monitor.js +380 -0
- package/src/movefile.js +30 -0
- package/src/optionsCheck.js +54 -0
- package/src/randstring.js +23 -0
- package/src/router.js +682 -0
- package/src/sendmsg.js +27 -0
- package/src/strong.js +72 -0
- package/src/token/token.js +461 -0
- package/src/topbit.js +1293 -0
- package/src/versionCheck.js +31 -0
- package/test/test-bigctx.js +29 -0
- package/test/test-daemon-args.js +7 -0
- package/test/test-ext.js +81 -0
- package/test/test-find.js +69 -0
- package/test/test-route-sort.js +71 -0
- package/test/test-route.js +49 -0
- package/test/test-route2.js +51 -0
- package/test/test-run-args.js +7 -0
- package/test/test-url.js +52 -0
- package/main.js +0 -0
package/bin/app.js
ADDED
package/bin/loadinfo.sh
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
if [ "$#" -eq 0 ] ; then
|
|
4
|
+
echo "usage: $0 [PATH]"
|
|
5
|
+
echo "example: $0 /tmp/loadinfo.log"
|
|
6
|
+
exit 0
|
|
7
|
+
fi
|
|
8
|
+
|
|
9
|
+
if [ ! -f "$1" ] ; then
|
|
10
|
+
echo "$1 is not a file"
|
|
11
|
+
exit 1
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
while clear ; do
|
|
15
|
+
cat "$1"
|
|
16
|
+
sleep 0.35
|
|
17
|
+
done
|
|
18
|
+
|
package/bin/new-ctl.js
ADDED
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
'use strict'
|
|
4
|
+
|
|
5
|
+
let simple_mode = false
|
|
6
|
+
|
|
7
|
+
let type_context = `\n//!!注意:以下注释是为了能够在支持jsdoc的代码编辑器中提示以及方便查阅提供,不需要可以去掉。
|
|
8
|
+
/**
|
|
9
|
+
* ---------------------- ctx.ext模块具备的方法 -----------------------------
|
|
10
|
+
*
|
|
11
|
+
* @typedef {object} ext
|
|
12
|
+
* @property {function} extName(filename: string) - 解析文件扩展名。
|
|
13
|
+
* @property {function} makeName(filename: string) - 生成唯一文件名,默认为时间字符串+随机数:2021-01-01_12-12-23_27789.jpg,filename主要用于获取扩展名。
|
|
14
|
+
* @property {function} nrand(n, m) - 返回两个数之间的随机数。
|
|
15
|
+
* @property {function} uuid() - 返回唯一字符串用于唯一ID,支持标准的8-4-4-4-12和短字符串8-2-2-4两种模式(传递参数为true)。
|
|
16
|
+
* @property {function} timestr() - 默认返回年-月-日_时-分-秒,没有空格,方便保存和解析。
|
|
17
|
+
* @property {function} sha1(text, encoding = 'hex')
|
|
18
|
+
* @property {function} sha256(text, encoding = 'hex')
|
|
19
|
+
* @property {function} sha512(text, encoding = 'hex')
|
|
20
|
+
* @property {function} sm3(text, encoding = 'hex')
|
|
21
|
+
* @property {function} hmacsha1(text, key, encoding = 'hex')
|
|
22
|
+
* @property {function} pipe(filename: string, reply: object)
|
|
23
|
+
*
|
|
24
|
+
* 更多参考:{@link https://gitee.com/daoio/titbit/wikis/helper-function}
|
|
25
|
+
*/
|
|
26
|
+
/**
|
|
27
|
+
* --------------------------------- 请求上下文 -----------------------------------------
|
|
28
|
+
*
|
|
29
|
+
* @typedef {object} context
|
|
30
|
+
* @property {string} version - 协议版本,字符串类型,为'1.1' 或 '2' 或 '3'。
|
|
31
|
+
* @property {number} major - 协议主要版本号,1、2、3分别表示HTTP/1.1 HTTP/2 HTTP/3。
|
|
32
|
+
* @property {string} method - 请求类型,GET POST等HTTP请求类型,大写字母的字符串。
|
|
33
|
+
* @property {string} path - 具体请求的路径,比如 /x/y。
|
|
34
|
+
* @property {string} routepath - 实际执行请求的路由字符串,比如 /x/:id。
|
|
35
|
+
* @property {boolean} isUpload - 是否为上传文件请求,此时就是检测消息头content-type是否为multipart/form-data格式。
|
|
36
|
+
* @property {object} box - 默认为空对象,可以添加任何属性值,用来动态传递给下一层组件需要使用的信息。
|
|
37
|
+
* @property {object} query - url传递的参数。
|
|
38
|
+
* @property {object} param - 路由参数。
|
|
39
|
+
* @property {object} headers - 指向request.headers。
|
|
40
|
+
* @property {object} files - 上传文件保存的信息。
|
|
41
|
+
* @property {(object|string|buffer|null)} body - body请求体的数据,具体格式需要看content-type,一般为字符串或者对象,也可能是buffer。
|
|
42
|
+
* @property {object} request HTTP/1.1 - 就是http模块request事件的参数IncomingMessage对象,HTTP/2 指向stream对象。
|
|
43
|
+
* @property {object} reply - HTTP/1.1协议,指向response,HTTP/2 指向stream。
|
|
44
|
+
* @property {object} service - 用于依赖注入的对象,指向app.service。
|
|
45
|
+
* @property {function} moveFile(file: object) - 用来移动上传的文件到指定路径,file是通过getFile获取的文件对象。
|
|
46
|
+
* @property {function} getFile(name: string, index = 0) - 根据上传名获取上传的文件,如果index是-1表示获取整个数组。
|
|
47
|
+
* @property {function} sendHeader() - 发送消息头,针对http/2设计,http/1.1只是一个空函数,为了代码保持一致。
|
|
48
|
+
* @property {function} setHeader(key: string, value: string|array)
|
|
49
|
+
* @property {function} send(body: string|object|buffer) - 设置要返回的body数据。
|
|
50
|
+
* @property {function} status(code: null | number) - 设置状态码,默认为null表示返回状态码。
|
|
51
|
+
* @property {ext} ext - 指向ext模块,提供了一些助手函数,具体参考wiki。
|
|
52
|
+
*
|
|
53
|
+
* 更多参考:{@link https://gitee.com/daoio/titbit/blob/master/README.md#%E8%AF%B7%E6%B1%82%E4%B8%8A%E4%B8%8B%E6%96%87}
|
|
54
|
+
*/
|
|
55
|
+
`
|
|
56
|
+
|
|
57
|
+
let head_hint = `/**********************************************************************
|
|
58
|
+
提示:
|
|
59
|
+
表单提交或异步请求,对应于POST或PUT请求,对应函数post和put,提交的请求体数据通过 ctx.body 获取。
|
|
60
|
+
|
|
61
|
+
路由参数通过 ctx.param 获取,示例:let id = ctx.param.id
|
|
62
|
+
|
|
63
|
+
url参数(?a=1&b=2)通过 ctx.query 获取,示例:let name = ctx.query.name
|
|
64
|
+
|
|
65
|
+
使用ctx.getFile(name)获取上传的文件,示例:let f = ctx.getFile('image')
|
|
66
|
+
**********************************************************************/\n\n`
|
|
67
|
+
|
|
68
|
+
function fmt_ctx_param(text) {
|
|
69
|
+
let ctx_param = `
|
|
70
|
+
/**
|
|
71
|
+
* ${text}
|
|
72
|
+
* @param {context} ctx
|
|
73
|
+
* @returns
|
|
74
|
+
*/
|
|
75
|
+
`
|
|
76
|
+
return ctx_param
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const fs = require('fs')
|
|
80
|
+
|
|
81
|
+
function makeController(name) {
|
|
82
|
+
let modname = name
|
|
83
|
+
if (!(/^[A-Z].*/).test(name)) {
|
|
84
|
+
modname = name.substring(0, 1).toUpperCase() + name.substring(1)
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
return `'use strict'\n\n`
|
|
88
|
+
+ (simple_mode ? '' : head_hint)
|
|
89
|
+
+ `class ${modname} {\n\n`
|
|
90
|
+
+ ` constructor() {\n`
|
|
91
|
+
+ ` //param用于指定最后的路由参数,默认就是/:id\n`
|
|
92
|
+
+ ` //若要改变路由,则可以设置此属性,比如设置为/:name\n`
|
|
93
|
+
+ ` //this.param = '/:id'\n`
|
|
94
|
+
+ ` }\n\n`
|
|
95
|
+
+ ` //控制器类初始化后会执行此函数。\n`
|
|
96
|
+
+ ` //service默认是app.service,此参数通过titbit-loader初始化的initArgs选项进行控制。\n`
|
|
97
|
+
+ ` async init(service) {\n`
|
|
98
|
+
+ ` \n`
|
|
99
|
+
+ ` }\n\n`
|
|
100
|
+
+ (simple_mode ? '' : ` //以下方法,若不需要,要去掉,避免无意义的路由。\n`)
|
|
101
|
+
+ `${fmt_ctx_param('获取资源具体内容')}`
|
|
102
|
+
+ ` async get(ctx) {\n\n`
|
|
103
|
+
+ ` }\n`
|
|
104
|
+
+ `${fmt_ctx_param('创建资源')}`
|
|
105
|
+
+ ` async post(ctx) {\n\n`
|
|
106
|
+
+ ` }\n`
|
|
107
|
+
+ `${fmt_ctx_param('更新资源')}`
|
|
108
|
+
+ ` async put(ctx) {\n\n`
|
|
109
|
+
+ ` }\n`
|
|
110
|
+
+ `${fmt_ctx_param('GET请求,用于获取资源列表')}`
|
|
111
|
+
+ ` async list(ctx) {\n\n`
|
|
112
|
+
+ ` }\n`
|
|
113
|
+
+ `${fmt_ctx_param('删除资源')}`
|
|
114
|
+
+ ` async _delete(ctx) {\n\n`
|
|
115
|
+
+ ` }\n`
|
|
116
|
+
+ `}\n\nmodule.exports = ${modname}\n`
|
|
117
|
+
+ (simple_mode ? '' : `${type_context}`)
|
|
118
|
+
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
let limitName = [
|
|
122
|
+
'async', 'await', 'for', 'of', 'if', 'else', 'switch', 'function', 'delete', 'new', 'case',
|
|
123
|
+
'require', 'import', 'export', 'exports', 'process', 'global', 'this', 'let', 'const', 'var',
|
|
124
|
+
'class', 'return', 'module', 'do', 'while', 'catch', 'try', 'break', 'boolean', 'instanceof',
|
|
125
|
+
'typeof', 'continue', 'fetch', 'globalThis', 'queueMicrotask'
|
|
126
|
+
]
|
|
127
|
+
|
|
128
|
+
let name_preg = /^[A-Za-z_][A-Za-z0-9_\-]{0,50}$/i
|
|
129
|
+
|
|
130
|
+
function checkName (name) {
|
|
131
|
+
return name_preg.test(name)
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function parseNameDir (name) {
|
|
135
|
+
let ind = name.indexOf('/')
|
|
136
|
+
let hasJS = (name.length > 3 && name.substring(name.length-3) === '.js')
|
|
137
|
+
|
|
138
|
+
if (ind > 0) {
|
|
139
|
+
let narr = name.split('/')
|
|
140
|
+
let real_name = narr[narr.length-1]
|
|
141
|
+
return {
|
|
142
|
+
dir: `/${narr[narr.length-2]}`,
|
|
143
|
+
name: hasJS ? real_name.substring(0, real_name.length-3) : real_name
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
dir : '',
|
|
149
|
+
name: hasJS ? name.substring(0, name.length-3) : name
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
function filterName (name) {
|
|
154
|
+
return (limitName.indexOf(name) >= 0 ? `_${name}` : name)
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
let cdir = 'controller'
|
|
158
|
+
|
|
159
|
+
let clist = []
|
|
160
|
+
|
|
161
|
+
//let model_name = ''
|
|
162
|
+
|
|
163
|
+
for (let i = 2; i < process.argv.length; i++) {
|
|
164
|
+
if (process.argv[i].indexOf('--cdir=') === 0) {
|
|
165
|
+
|
|
166
|
+
let t = process.argv[i].substring('--cdir='.length)
|
|
167
|
+
|
|
168
|
+
if (t.length > 0) {
|
|
169
|
+
cdir = t
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
continue
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
if (process.argv[i] === '-s' || process.argv[i] === '--pure' || process.argv[i] === '--simple')
|
|
176
|
+
{
|
|
177
|
+
simple_mode = true
|
|
178
|
+
continue
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/* if (process.argv.indexOf('--model=') === 0) {
|
|
182
|
+
let mname = process.argv[i].substring('--model='.length)
|
|
183
|
+
if (mname.length > 0 && (/^[a-z0-9_][a-z\-_0-9]{0,100}$/i).test(mname)) {
|
|
184
|
+
model_name = mname
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
continue
|
|
188
|
+
} */
|
|
189
|
+
|
|
190
|
+
clist.push(process.argv[i])
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
try {
|
|
194
|
+
fs.accessSync(cdir)
|
|
195
|
+
} catch (err) {
|
|
196
|
+
fs.mkdirSync(cdir)
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
let nd
|
|
200
|
+
let cpath
|
|
201
|
+
|
|
202
|
+
for (let c of clist) {
|
|
203
|
+
nd = parseNameDir(c)
|
|
204
|
+
|
|
205
|
+
if (!checkName(nd.name)) {
|
|
206
|
+
console.error(`${nd.name} 不符合命名要求,要求字母数字,字母开头,支持连字符和下划线(- 和 _)。(the name is illegal.)`)
|
|
207
|
+
continue
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
let modname = nd.name.replace(/\-+/ig, '')
|
|
211
|
+
|
|
212
|
+
if (nd.dir) {
|
|
213
|
+
try {
|
|
214
|
+
fs.accessSync(`${cdir}${nd.dir}`)
|
|
215
|
+
} catch (err) {
|
|
216
|
+
fs.mkdirSync(`${cdir}${nd.dir}`)
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
cpath = `${cdir}${nd.dir}/${nd.name}.js`
|
|
221
|
+
|
|
222
|
+
try {
|
|
223
|
+
fs.accessSync(cpath)
|
|
224
|
+
console.error(`${c} 已经存在。`)
|
|
225
|
+
continue
|
|
226
|
+
} catch (err) {}
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
fs.writeFileSync(cpath, makeController(filterName(modname)), {encoding: 'utf8'})
|
|
230
|
+
} catch (err) {
|
|
231
|
+
console.error(err)
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
}
|
package/bin/newapp.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
//process.chdir(__dirname)
|
|
5
|
+
|
|
6
|
+
const fs = require('fs')
|
|
7
|
+
|
|
8
|
+
let fname = 'app.js'
|
|
9
|
+
|
|
10
|
+
if (process.argv.length > 2) {
|
|
11
|
+
fname = process.argv[2]
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
//let curdir = __dirname + '/../../'
|
|
15
|
+
let appfile = __dirname + '/app.js'
|
|
16
|
+
|
|
17
|
+
try {
|
|
18
|
+
fs.accessSync(fname)
|
|
19
|
+
console.log('文件已存在')
|
|
20
|
+
} catch (err) {
|
|
21
|
+
fs.writeFileSync(fname, fs.readFileSync(appfile))
|
|
22
|
+
}
|
package/demo/allow.js
ADDED
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const titbit = require('../src/topbit.js');
|
|
4
|
+
|
|
5
|
+
const app = new titbit({
|
|
6
|
+
debug : true,
|
|
7
|
+
allow : new Set(['127.0.0.1']),
|
|
8
|
+
maxIPRequest: 2,
|
|
9
|
+
unitTime: 10,
|
|
10
|
+
useLimit: true,
|
|
11
|
+
maxConn: 2000,
|
|
12
|
+
//http2: true,
|
|
13
|
+
showLoadInfo: true,
|
|
14
|
+
loadInfoType : 'text',
|
|
15
|
+
globalLog : true,
|
|
16
|
+
logType: 'stdio',
|
|
17
|
+
loadInfoFile : '/tmp/loadinfo.log'
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
app.use(async (c, next) => {
|
|
21
|
+
console.log('pre middleware start');
|
|
22
|
+
console.log(c.group, c.name, c.method, c.path);
|
|
23
|
+
await next(c);
|
|
24
|
+
console.log('pre middleware end');
|
|
25
|
+
}, {pre : true});
|
|
26
|
+
|
|
27
|
+
app.use(async (c, next) => {
|
|
28
|
+
console.log('middleware 1');
|
|
29
|
+
await next(c);
|
|
30
|
+
console.log('middleware 1 end');
|
|
31
|
+
}, 'home');
|
|
32
|
+
|
|
33
|
+
app.use(async (c, next) => {
|
|
34
|
+
console.log('middleware 2');
|
|
35
|
+
c.body.say = '你好';
|
|
36
|
+
await next(c);
|
|
37
|
+
console.log('middleware 2 end');
|
|
38
|
+
}, {group: 'test', method: 'POST'});
|
|
39
|
+
|
|
40
|
+
app.use(async (c, next) => {
|
|
41
|
+
console.log('middleware 3');
|
|
42
|
+
if (c.query.say == 'hey') {
|
|
43
|
+
c.to('你好,test 接口 GET请求结束。');
|
|
44
|
+
} else {
|
|
45
|
+
await next(c);
|
|
46
|
+
}
|
|
47
|
+
console.log('middleware 3 end');
|
|
48
|
+
}, {group: 'test', method : 'GET'});
|
|
49
|
+
|
|
50
|
+
app.use(async (c, next) => {
|
|
51
|
+
console.log('set body size');
|
|
52
|
+
c.maxBody = 24;
|
|
53
|
+
await next(c);
|
|
54
|
+
}, {name: 'test-post', pre: true});
|
|
55
|
+
|
|
56
|
+
app.use(async (c, next) => {
|
|
57
|
+
console.log('middleware 4');
|
|
58
|
+
c.body.x = 12;
|
|
59
|
+
await next(c);
|
|
60
|
+
console.log('middleware 4 end');
|
|
61
|
+
}, 'test-post');
|
|
62
|
+
|
|
63
|
+
app.get('/', async c => {
|
|
64
|
+
c.to('ok');
|
|
65
|
+
}, 'home');
|
|
66
|
+
|
|
67
|
+
app.get('/test', async c => {
|
|
68
|
+
c.to(c.name);
|
|
69
|
+
}, {group: 'test', name : 'test'});
|
|
70
|
+
|
|
71
|
+
app.post('/test', async c => {
|
|
72
|
+
c.to(c.body);
|
|
73
|
+
}, {group: 'test', name : 'test-post'});
|
|
74
|
+
|
|
75
|
+
app.post('/transmit', async c => {
|
|
76
|
+
c.to('ok');
|
|
77
|
+
}, 'transmit');
|
|
78
|
+
|
|
79
|
+
app.use(async (c, next) => {
|
|
80
|
+
let total = 0;
|
|
81
|
+
|
|
82
|
+
c.box.dataHandle = (data) => {
|
|
83
|
+
total += data.length;
|
|
84
|
+
if (total > 32) {
|
|
85
|
+
c.response.statusCode = 413;
|
|
86
|
+
c.response.end('太多了,限制32字节以内');
|
|
87
|
+
return ;
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
await next(c);
|
|
92
|
+
|
|
93
|
+
console.log(total, 'bytes');
|
|
94
|
+
|
|
95
|
+
}, {pre: true, method: 'POST', name: 'transmit'});
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
app.daemon(2034, 2);
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
-----BEGIN CERTIFICATE-----
|
|
2
|
+
MIIC/jCCAeagAwIBAgIJAM7LJO+3smgrMA0GCSqGSIb3DQEBCwUAMBQxEjAQBgNV
|
|
3
|
+
BAMMCWxvY2FsaG9zdDAeFw0xOTAzMTMxNDI1NDVaFw0xOTA0MTIxNDI1NDVaMBQx
|
|
4
|
+
EjAQBgNVBAMMCWxvY2FsaG9zdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoC
|
|
5
|
+
ggEBANlxw2tilmgttCHtzCkQRlbLicxSRjXEY/5JXSUZdKNGlBFLovclK/OrpixO
|
|
6
|
+
c9ijw6z6TPT3yvYkF2r1GKWYZWZeSdIfnd3M8UCJr06Jh8DAFZ14YUjyPcEo0Kfi
|
|
7
|
+
rJ/wecxRKsO1MehXo5YfgQ+IruuYYxyEhZOV8cmvXb7gi7hsKTnJ+2Xogef8sxlF
|
|
8
|
+
bHC+ySqHsODA2W1kX03jWUq2jo3j0D1yJ+8B103e2CMeiqjuIhvAzP700IOLNF2G
|
|
9
|
+
fPZ6RMLRWOTMpRMy5DtDKs/mX6Ohm7oVbpqhvC4QqP84+RyU30+/ThnU36K40rCH
|
|
10
|
+
13VBi/4IThvXjjMCK06famj4bA0CAwEAAaNTMFEwHQYDVR0OBBYEFGpeaaG9leYI
|
|
11
|
+
W9rfUeTlgU7F0FP7MB8GA1UdIwQYMBaAFGpeaaG9leYIW9rfUeTlgU7F0FP7MA8G
|
|
12
|
+
A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQELBQADggEBALtt9KQO1erWzNZGFN7h
|
|
13
|
+
NIsxMAg0DifUUR4HzOwVsOSjlxdkzkOylF7yYROptUIluuF90pC7RQ1EztwlPqTI
|
|
14
|
+
XrpLhU/JJcAx80Z+9XJJa3hS+mctaJ+Uv0lLY5uQgrYJCsK+qJ9XMOBjA8Uziyu/
|
|
15
|
+
mFgvfW/5Ts0mwTRn0MKLf2vRIH4F3syeiVLTxDJ0s6fKfrCryNSo8LGYAOfr0rCg
|
|
16
|
+
4BbTyDt1UB+nTY6xM12zybJ/OtIZtfRG5JZHHsB1kbsOw+WzWrcKbsqncrivGt8m
|
|
17
|
+
XgNCpvSLE4v+giPocOkX6ySq+RCTFvdlhv1bCsHlOW5vMpSur0SQLcnSUnRfk41W
|
|
18
|
+
BuI=
|
|
19
|
+
-----END CERTIFICATE-----
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
-----BEGIN PRIVATE KEY-----
|
|
2
|
+
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDZccNrYpZoLbQh
|
|
3
|
+
7cwpEEZWy4nMUkY1xGP+SV0lGXSjRpQRS6L3JSvzq6YsTnPYo8Os+kz098r2JBdq
|
|
4
|
+
9RilmGVmXknSH53dzPFAia9OiYfAwBWdeGFI8j3BKNCn4qyf8HnMUSrDtTHoV6OW
|
|
5
|
+
H4EPiK7rmGMchIWTlfHJr12+4Iu4bCk5yftl6IHn/LMZRWxwvskqh7DgwNltZF9N
|
|
6
|
+
41lKto6N49A9cifvAddN3tgjHoqo7iIbwMz+9NCDizRdhnz2ekTC0VjkzKUTMuQ7
|
|
7
|
+
QyrP5l+joZu6FW6aobwuEKj/OPkclN9Pv04Z1N+iuNKwh9d1QYv+CE4b144zAitO
|
|
8
|
+
n2po+GwNAgMBAAECggEAZN35+dlszfzNf6Owvie3iVG3pVlRCmYEwJPFqo0JZyg5
|
|
9
|
+
TWCZwy2yGsG4PvtRj+A/yAEAK+66br3FQy9Y9JAiEX+RnPBfqeEE1JxJ/xObLpWs
|
|
10
|
+
MTUDY/RDI1RMnmRvEW5bAaVxQgHOmen1j5EjrFIKWm2BJFxxHkpDM/yubvn4tl5T
|
|
11
|
+
JxQk+CSNsLFZ57jd8JyIugOOql7HQNyY21Si3c9Q2HXDbXvIv/s0Bw1PB1xGXBbI
|
|
12
|
+
/58wz/dSajNIuYbJB3Q85PRLo12Xkb+3L5GUJDoOqrOG3aZn9OM0uNpvUNaByPyT
|
|
13
|
+
wL86vlyLQAlLreAL0GDCiZAMalp1JKmNNSGqMa33oQKBgQD0Qo3m4+EW0uvijF8S
|
|
14
|
+
dWdHeKT4lmoowpTCQiZpcZmJ1iWkpxAovjMwZf48j+giLIg7cYpxQHGTmryBb3F+
|
|
15
|
+
bV3Vcc4QSD1r8tAgnI+WLA2rn698syuxsAG9UUpzzQgjLRY8298OIJJS3kypfCse
|
|
16
|
+
hjoLwUt6kbopNn/kKXSQ2krc6QKBgQDj5UMi5Yhq5Rvof5r2j+Wr9mlYdEMOV8zc
|
|
17
|
+
u5fmkrSpo/li16z7XHX/e1Srq4EAcbX7XBdZc9G5injVOrtmpeZC0+/8lU6nN4Po
|
|
18
|
+
q0Ab5Wra5Ws5WU7bog2poHac+tWGItds6R5bfwes0f4AtSS3623FnynB9kOPycST
|
|
19
|
+
ZeHSdtIPhQKBgAGtW1AUjH0doaUClbyItdbVyzwxvDTfcSoMTjs3HnjF0ahZxVCi
|
|
20
|
+
TbOtX5uG2W8yoxTVaL/yU1VSIK062KqnkZdfmqyd8l4FYsx2hr3fO5DMHeZbTJeB
|
|
21
|
+
v+FO55X3+HBVZOuyDswICTkscZZQVfN1tHxULXKAAak6yJIGfthnx0/RAoGAJLwb
|
|
22
|
+
6lAdgT2VFhEbpYrkdqetq3hyJqm4eAw1HBGh1YZ8+JXTaGErFBeJOnLWxH+P2giq
|
|
23
|
+
Kt0kfUf42kYxVwZ+617GXGyk1Qd519Ni7hw48Tfx5LikoXqpwSIAfKViLdEH8KJT
|
|
24
|
+
JmR/lDf1PZ/1X0Av3Z8eWAmeMltPuIK/t/E3QxECgYAl76olBcjS+0LjOp10BnnZ
|
|
25
|
+
M4VM4JyqjXH21OQ7YcckhugHcF12A8Y1gUsZIL/NoIEECFeor4spF2AD74AFzyPw
|
|
26
|
+
+WUR2BETzvsQxEp0F096LXkRT0H8IlT3ZwUbdP0//NQ4KdLyn3o+8NsDXiXqeVpp
|
|
27
|
+
4Ouzs+qyLyxI2/17yodFRA==
|
|
28
|
+
-----END PRIVATE KEY-----
|
package/demo/extends.js
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const titbit = require('../lib/titbit.js')
|
|
4
|
+
|
|
5
|
+
const app = new titbit({
|
|
6
|
+
debug: true,
|
|
7
|
+
loadInfoFile: '--mem',
|
|
8
|
+
http2: true,
|
|
9
|
+
allowHTTP1: true,
|
|
10
|
+
key: __dirname + '/../cache/rsa/localhost-privkey.pem',
|
|
11
|
+
cert: __dirname + '/../cache/rsa/localhost-cert.pem'
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
/*
|
|
15
|
+
app.midware.addFinal = () => {
|
|
16
|
+
return async (c, next) => {
|
|
17
|
+
return c.reply.end('ok')
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
app.pre(async (c, next) => {
|
|
22
|
+
return c.reply.end('ok')
|
|
23
|
+
})
|
|
24
|
+
*/
|
|
25
|
+
|
|
26
|
+
app.get('/home', async c => {
|
|
27
|
+
c.setHeader('x-key', Math.random()).sendHeader().send('home page')
|
|
28
|
+
}, '@home')
|
|
29
|
+
|
|
30
|
+
app.get('/', async c => {
|
|
31
|
+
for (let i = 0; i < 10; i++) {
|
|
32
|
+
c.write(`${i} ${Math.random()}\n`)
|
|
33
|
+
await c.ext.delay()
|
|
34
|
+
}
|
|
35
|
+
c.send('home page')
|
|
36
|
+
}, '@home')
|
|
37
|
+
|
|
38
|
+
app.use(async (ctx, next) => {
|
|
39
|
+
console.log('group', ctx.group, ctx.path)
|
|
40
|
+
await next()
|
|
41
|
+
console.log('group', ctx.group, ctx.path, 'end')
|
|
42
|
+
}, '@home')
|
|
43
|
+
|
|
44
|
+
let mid_timing = async (c, next) => {
|
|
45
|
+
console.log('time start')
|
|
46
|
+
console.time('request')
|
|
47
|
+
await next()
|
|
48
|
+
console.timeEnd('request')
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
app.trace('/o', async c => {})
|
|
52
|
+
|
|
53
|
+
app.use(async (c, next) => {
|
|
54
|
+
console.log('global request')
|
|
55
|
+
await next()
|
|
56
|
+
console.log('global request end\n')
|
|
57
|
+
|
|
58
|
+
}, {pre: true})
|
|
59
|
+
|
|
60
|
+
app.use(async (c, next) => {
|
|
61
|
+
console.log('global pre')
|
|
62
|
+
await next()
|
|
63
|
+
console.log('global pre end')
|
|
64
|
+
|
|
65
|
+
}, {pre: true})
|
|
66
|
+
|
|
67
|
+
app.router.group('/api', (route) => {
|
|
68
|
+
route.get('/test', async c => {
|
|
69
|
+
c.send('api test')
|
|
70
|
+
})
|
|
71
|
+
|
|
72
|
+
route.get('/stream', async c => {
|
|
73
|
+
for (let i = 0; i < 10; i++) {
|
|
74
|
+
await c.ext.delay(30)
|
|
75
|
+
c.write(`${i} ${Math.random()} ${Date.now()}\n`)
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
route.get('/:name', async c => {
|
|
80
|
+
c.send(c.param)
|
|
81
|
+
}, 'name')
|
|
82
|
+
|
|
83
|
+
route.use(async (ctx, next) => {
|
|
84
|
+
console.log('name test')
|
|
85
|
+
await next()
|
|
86
|
+
console.log('name test end')
|
|
87
|
+
}, 'name')
|
|
88
|
+
|
|
89
|
+
route.trace('/o', async c => {})
|
|
90
|
+
})
|
|
91
|
+
.use(async (c, next) => {
|
|
92
|
+
console.log(c.group, c.path, c.routepath)
|
|
93
|
+
await next()
|
|
94
|
+
})
|
|
95
|
+
.pre(async (c, next) => {
|
|
96
|
+
console.log('pre', c.method, c.headers)
|
|
97
|
+
await next()
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
app.middleware([mid_timing,], {pre: true}).group('验证', route => {
|
|
101
|
+
route.use(async (ctx, next) => {
|
|
102
|
+
console.log(' new route use test')
|
|
103
|
+
await next()
|
|
104
|
+
console.log(' new route use end')
|
|
105
|
+
})
|
|
106
|
+
|
|
107
|
+
route.get('/c/:o/:p', async c => {
|
|
108
|
+
console.log(c.group, c.name)
|
|
109
|
+
c.send(c.param)
|
|
110
|
+
})
|
|
111
|
+
|
|
112
|
+
route.middleware([
|
|
113
|
+
async (c, next) => {
|
|
114
|
+
console.log(' group sub test')
|
|
115
|
+
await next()
|
|
116
|
+
console.log(' group sub test end')
|
|
117
|
+
},
|
|
118
|
+
|
|
119
|
+
[
|
|
120
|
+
async (c, next) => {
|
|
121
|
+
console.log(' group sub test 2')
|
|
122
|
+
await next()
|
|
123
|
+
console.log(' group sub test 2 end')
|
|
124
|
+
},
|
|
125
|
+
{pre: false}
|
|
126
|
+
]
|
|
127
|
+
], {pre: true, tag: 'sub'}).group('sub', r => {
|
|
128
|
+
|
|
129
|
+
r.get('/oo', async c => {
|
|
130
|
+
c.send(c.group)
|
|
131
|
+
})
|
|
132
|
+
|
|
133
|
+
r.middleware(async (c, next) => {
|
|
134
|
+
console.log('sub sub test')
|
|
135
|
+
await next()
|
|
136
|
+
}).group('/sub', subr => {
|
|
137
|
+
subr.get('/ok', async c => {
|
|
138
|
+
c.send(c.group)
|
|
139
|
+
})
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
})
|
|
143
|
+
|
|
144
|
+
})
|
|
145
|
+
|
|
146
|
+
app.group('测试', route => {
|
|
147
|
+
route.get('/test', async c => {
|
|
148
|
+
console.log(c.group, c.name)
|
|
149
|
+
c.send('test ok')
|
|
150
|
+
}, 'test')
|
|
151
|
+
})
|
|
152
|
+
.use(async (c, next) => {
|
|
153
|
+
console.log('测试组')
|
|
154
|
+
await next()
|
|
155
|
+
})
|
|
156
|
+
|
|
157
|
+
app.daemon({port: 1234}, 2)
|
|
158
|
+
|
|
159
|
+
//app.run(1234)
|
|
160
|
+
|
|
161
|
+
//app.isWorker && console.log(app.midware.midGroup)
|