topbit 2.0.0 → 3.0.1

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 (72) hide show
  1. package/README.cn.md +132 -177
  2. package/README.md +801 -592
  3. package/bin/new-ctl.js +7 -3
  4. package/demo/allow.js +13 -13
  5. package/demo/controller/api.js +15 -0
  6. package/demo/extends.js +5 -0
  7. package/demo/http2.js +34 -0
  8. package/demo/http2_proxy_backend.js +45 -0
  9. package/demo/http2proxy.js +48 -0
  10. package/demo/http_proxy_backend.js +44 -0
  11. package/demo/httpproxy.js +47 -0
  12. package/demo/loader.js +27 -0
  13. package/demo/log.js +1 -1
  14. package/demo/memlimit.js +1 -1
  15. package/demo/min.js +1 -1
  16. package/demo/serv.js +1 -1
  17. package/images/topbit-middleware.webp +0 -0
  18. package/images/topbit.png +0 -0
  19. package/package.json +7 -6
  20. package/src/_loadExtends.js +21 -0
  21. package/src/bodyparser.js +1 -1
  22. package/src/context1.js +19 -19
  23. package/src/context2.js +11 -8
  24. package/src/ctxpool.js +1 -0
  25. package/src/extends/Http2Pool.js +365 -0
  26. package/src/extends/__randstring.js +24 -0
  27. package/src/extends/cookie.js +44 -0
  28. package/src/extends/cors.js +334 -0
  29. package/src/extends/errorlog.js +252 -0
  30. package/src/extends/http2limit.js +126 -0
  31. package/src/extends/http2proxy.js +691 -0
  32. package/src/extends/jwt.js +217 -0
  33. package/src/extends/mixlogger.js +63 -0
  34. package/src/extends/paramcheck.js +266 -0
  35. package/src/extends/proxy.js +662 -0
  36. package/src/extends/realip.js +34 -0
  37. package/src/extends/referer.js +68 -0
  38. package/src/extends/resource.js +398 -0
  39. package/src/extends/session.js +174 -0
  40. package/src/extends/setfinal.js +50 -0
  41. package/src/extends/sni.js +48 -0
  42. package/src/extends/sse.js +293 -0
  43. package/src/extends/timing.js +111 -0
  44. package/src/extends/tofile.js +123 -0
  45. package/src/http1.js +15 -16
  46. package/src/http2.js +5 -5
  47. package/src/httpc.js +3 -3
  48. package/src/lib/npargv.js +354 -0
  49. package/src/lib/zipdata.js +45 -0
  50. package/src/middleware1.js +15 -16
  51. package/src/middleware2.js +4 -9
  52. package/src/token/token.js +4 -5
  53. package/src/topbit.js +13 -11
  54. package/test/{test-helper.js → test-ext.js} +1 -1
  55. package/test/test-route.js +1 -1
  56. package/cache/allow.js +0 -130
  57. package/cache/errserv.js +0 -45
  58. package/cache/minserv.js +0 -167
  59. package/cache/router.js +0 -84
  60. package/cache/servsock.js +0 -286
  61. package/cache/sni.js +0 -66
  62. package/images/titbit-middleware.png +0 -0
  63. package/images/titbit.png +0 -0
  64. package/tmp/buff-code +0 -134
  65. package/tmp/devplan +0 -9
  66. package/tmp/evt-test.js +0 -34
  67. package/tmp/fastParseUrl.js +0 -302
  68. package/tmp/router-rule.js +0 -559
  69. package/tmp/test-cdps.js +0 -122
  70. package/tmp/titbit.js +0 -1286
  71. /package/{cache/rsa → demo/cert}/localhost-cert.pem +0 -0
  72. /package/{cache/rsa → demo/cert}/localhost-privkey.pem +0 -0
@@ -0,0 +1,48 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs')
4
+ const tls = require('node:tls')
5
+
6
+ class SNI {
7
+ constructor(certs = {}) {
8
+ this.certs = {}
9
+
10
+ if (typeof certs !== 'object') {
11
+ throw new Error('必须传递key-value形式的配置,key是域名,value是证书路径')
12
+ }
13
+
14
+ let t = '';
15
+ for (let h in certs) {
16
+ t = certs[h]
17
+
18
+ if (t.key === undefined || t.cert === undefined) {
19
+ console.error(`${h} 没有设置key和cert`)
20
+ continue
21
+ }
22
+
23
+ try {
24
+ this.certs[h] = {
25
+ key : fs.readFileSync(t.key),
26
+ cert : fs.readFileSync(t.cert)
27
+ }
28
+ } catch (err) {
29
+ console.error(h, err.message)
30
+ continue
31
+ }
32
+
33
+ }
34
+ }
35
+
36
+ callback() {
37
+ return (servername, cb) => {
38
+ return cb(null, tls.createSecureContext(this.certs[servername]))
39
+ }
40
+ }
41
+
42
+ init(app) {
43
+ app.config.server.SNICallback = this.callback()
44
+ }
45
+
46
+ }
47
+
48
+ module.exports = SNI
@@ -0,0 +1,293 @@
1
+ 'use strict'
2
+
3
+ function fmtMessage(msg, withEnd=true) {
4
+ let text = ''
5
+
6
+ if (Array.isArray(msg)) {
7
+ let textarr = []
8
+
9
+ for (let m of msg) {
10
+ text = fmtMessage(m, false)
11
+ text && textarr.push(text)
12
+ }
13
+ if (textarr.length === 0) return ''
14
+
15
+ return textarr.join('\n\n') + '\n\n'
16
+ }
17
+
18
+ if (msg === null || msg === undefined || msg === '') {
19
+ return ''
20
+ }
21
+
22
+ let typ = typeof msg
23
+
24
+ if (typ === 'number') {
25
+ msg = `${msg}`
26
+ typ = 'string'
27
+ }
28
+
29
+ if (typ === 'object') {
30
+ if (!(msg.event || msg.data || msg.retry || msg.id)) return ''
31
+
32
+ if (msg.data === undefined) msg.data = ''
33
+
34
+ let datatype = typeof msg.data
35
+
36
+ switch (datatype) {
37
+ case 'number':
38
+ msg.data = msg.data.toString()
39
+ break
40
+ case 'object':
41
+ msg.data = JSON.stringify(msg.data).replaceAll('\n', '%0A')
42
+ break
43
+ case 'function':
44
+ msg.data = msg.data.toString().replaceAll('\n', '%0A')
45
+ break
46
+ case 'string':
47
+ msg.data = msg.data.replaceAll('\n', '%0A')
48
+ break
49
+
50
+ default:
51
+ msg.data = `${msg.data}`
52
+ }
53
+
54
+ text = `event: ${msg.event || 'message'}\ndata: ${msg.data}\n`
55
+ if (msg.id) {
56
+ text += `id: ${msg.id}\n`
57
+ }
58
+
59
+ if (msg.retry) {
60
+ text += `retry: ${msg.retry}\n`
61
+ }
62
+ } else if (typ === 'string') {
63
+ if (msg[0] !== ':') {
64
+ text = `data: ${msg.replaceAll('\n', '%0A')}\n`
65
+ } else {
66
+ text = msg.replaceAll('\n', '%0A') + '\n'
67
+ }
68
+ } else if (typ === 'function') {
69
+ text = `event: function\ndata: ${msg.toString().replaceAll('\n', '%0A')}\n`
70
+ }
71
+
72
+ if (withEnd) {
73
+ text += `\n\n`
74
+ }
75
+
76
+ return text
77
+ }
78
+
79
+ class SSE {
80
+
81
+ constructor(options = {}) {
82
+ this.timer = null
83
+ this.handle = null
84
+ this.timeSlice = 1000
85
+
86
+ this.retry = 0
87
+ this.timeout = 15000
88
+
89
+ this.fmtMsg = fmtMessage
90
+
91
+ this.handleClose = null
92
+ this.handleError = null
93
+
94
+ this.mode = 'timer'
95
+
96
+ for (let k in options) {
97
+ switch (k) {
98
+ case 'timeSlice':
99
+ case 'timeout':
100
+ case 'retry':
101
+ if (typeof options[k] === 'number' && options[k] >= 0) {
102
+ this[k] = options[k]
103
+ }
104
+ break
105
+
106
+ case 'handle':
107
+ case 'handleClose':
108
+ case 'handleError':
109
+ if (typeof options[k] === 'function') this[k] = optionsp[k]
110
+ break
111
+
112
+ case 'mode':
113
+ if (['timer', 'generator', 'yield'].indexOf(options[k]) >= 0)
114
+ this[k] = options[k]
115
+ break
116
+ }
117
+ }
118
+
119
+ }
120
+
121
+ async interval(ctx) {
122
+ if (!this.handle || typeof this.handle !== 'function') {
123
+ throw new Error('请设置handle为要处理的函数,然后再次运行。')
124
+ }
125
+
126
+ let self = this
127
+
128
+ if (self.timer) {
129
+ clearInterval(this.timer)
130
+ this.timer = null
131
+ }
132
+
133
+ return new Promise((rv, rj) => {
134
+ ctx.res.on('error', err => {
135
+ clearInterval(self.timer)
136
+ self.timer = null
137
+ rj(err)
138
+ })
139
+
140
+ ctx.res.on('close', () => {
141
+ clearInterval(self.timer)
142
+ self.timer = null
143
+ rv('sse closed')
144
+ })
145
+
146
+ self.timer = setInterval(async () => {
147
+ ctx.box.sseCount += 1
148
+ if (self.timeout > 0 && ctx.box.sseCount * self.timeSlice > self.timeout) {
149
+ if (self.retry > 0) {
150
+ ctx.sendmsg({data: 'timeout', retry: self.retry})
151
+ }
152
+ return ctx.res.end()
153
+ }
154
+
155
+ try {
156
+ await self.handle(ctx)
157
+ } catch (err) {
158
+ clearInterval(self.timer)
159
+ self.timer = null
160
+ rj(err)
161
+ }
162
+ }, self.timeSlice || 1000)
163
+ })
164
+
165
+ }
166
+
167
+ async moment(t) {
168
+ return new Promise((rv) => {
169
+ setTimeout(rv, t)
170
+ })
171
+ }
172
+
173
+ gn(ctx) {
174
+ if (!this.handle || typeof this.handle !== 'function') {
175
+ throw new Error('请设置handle为要处理的函数,然后再次运行。')
176
+ }
177
+
178
+ let self = this
179
+
180
+ ctx.box.sseNext = true
181
+
182
+ ctx.res.on('error', err => {
183
+ ctx.box.sseNext = false
184
+ ctx.box.sseError = err
185
+ })
186
+
187
+ ctx.res.on('close', () => {
188
+ ctx.box.sseNext = false
189
+ })
190
+
191
+ return async function * () {
192
+ while (true) {
193
+ let tm = Date.now()
194
+
195
+ if (self.timeout > 0 && (tm - ctx.box.sseTime) > self.timeout) {
196
+ if (self.retry > 0) {
197
+ ctx.sendmsg({data: 'timeout', retry: self.retry})
198
+ }
199
+ return
200
+ }
201
+ ctx.box.sseCount += 1
202
+ try {
203
+ await self.handle(ctx)
204
+ } catch (err) {
205
+ ctx.box.sseNext = false
206
+ ctx.box.sseError = err
207
+ }
208
+
209
+ if (ctx.box.sseNext) {
210
+ yield tm
211
+ } else {
212
+ break
213
+ }
214
+ }
215
+ }
216
+
217
+ }
218
+
219
+ async rungn(ctx) {
220
+ let yn = this.gn(ctx)
221
+ let r
222
+ let y = yn()
223
+
224
+ while (true) {
225
+ r = await y.next()
226
+
227
+ if (r.done) break
228
+
229
+ if (this.timeSlice > 0) await this.moment(this.timeSlice)
230
+ }
231
+
232
+ if (ctx.box.sseError) {
233
+ if (this.handleError && typeof this.handleError === 'function')
234
+ this.handleError(ctx.box.sseError, ctx)
235
+ else throw ctx.box.sseError
236
+ } else if (this.handleClose && typeof this.handleClose === 'function') {
237
+ this.handleClose(ctx)
238
+ }
239
+ }
240
+
241
+ autoRun(ctx) {
242
+ if (this.mode === 'timer') {
243
+ return this.interval(ctx)
244
+ .then(data => {
245
+ if (typeof this.handleClose === 'function') this.handleClose(ctx)
246
+ })
247
+ .catch(err => {
248
+ if (typeof this.handleError === 'function') {
249
+ this.handleError(err, ctx)
250
+ } else {
251
+ throw err
252
+ }
253
+ })
254
+ } else {
255
+ ctx.box.sseTime = Date.now()
256
+ return this.rungn(ctx)
257
+ }
258
+ }
259
+
260
+ mid() {
261
+ let self = this
262
+
263
+ return async (ctx, next) => {
264
+ ctx.setHeader('content-type', 'text/event-stream;charset=utf-8').sendHeader()
265
+ ctx.sse = self
266
+ //用于统计是否超时断开并发送retry
267
+ ctx.box.sseCount = 0
268
+ if (!ctx.sendmsg || typeof ctx.sendmsg !== 'function') {
269
+ ctx.sendmsg = (msg, cb=undefined) => {
270
+ let emsg = fmtMessage(msg)
271
+ if (emsg) return ctx.res.write(emsg, cb)
272
+ }
273
+ }
274
+
275
+ ctx.res.setTimeout(self.timeout, () => {
276
+ if (ctx.res.writable) ctx.res.end()
277
+ })
278
+
279
+ //http2协议需要设置session超时,否则如果默认的服务超时设置比self.timeout短,会导致无法收到消息。
280
+ if (ctx.major == 2 && ctx.res.session && ctx.res.session.listenerCount) {
281
+ //http2的session会保持连接,如果stream超时关闭后,session可能会维持连接,此时有可能会复用session。
282
+ if (ctx.res.session.listenerCount('timeout') < 2) {
283
+ ctx.res.session.setTimeout(self.timeout, () => {})
284
+ }
285
+ }
286
+
287
+ await self.autoRun(ctx)
288
+ }
289
+ }
290
+
291
+ }
292
+
293
+ module.exports = SSE
@@ -0,0 +1,111 @@
1
+ 'use strict'
2
+
3
+ const fs = require('node:fs')
4
+
5
+ class Timing {
6
+
7
+ constructor(options = {}) {
8
+
9
+ /**
10
+ * route保存所有路由的最近耗时记录。
11
+ * maxLimit是保存记录上限。
12
+ */
13
+
14
+ this.route = {
15
+ GET : new Map(),
16
+ POST : new Map(),
17
+ PUT : new Map(),
18
+ DELETE : new Map(),
19
+ OPTIONS : new Map(),
20
+ PATCH : new Map()
21
+ }
22
+
23
+ this.maxLimit = 100
24
+
25
+ this.test = false
26
+
27
+ this.logfile = ''
28
+
29
+ if (typeof options !== 'object') {
30
+ options = {}
31
+ }
32
+
33
+ for (let k in options) {
34
+ switch (k) {
35
+ case 'test':
36
+ this.test = options[k]
37
+ break
38
+
39
+ case 'logfile':
40
+ this.logfile = options[k]
41
+ break
42
+ }
43
+ }
44
+
45
+ }
46
+
47
+ mid() {
48
+ let self = this
49
+
50
+ return async (c, next) => {
51
+
52
+ let start_time = Date.now()
53
+
54
+ await next()
55
+
56
+ let end_time = Date.now()
57
+
58
+ let time_consume = end_time - start_time
59
+
60
+ if (self.route[c.method] !== undefined) {
61
+ if (!self.route[c.method].has(c.routepath)) {
62
+ self.route[c.method].set(c.routepath, {
63
+ total : 1,
64
+ consume: time_consume
65
+ })
66
+ } else {
67
+ let t = self.route[c.method].get(c.routepath)
68
+ if (t.total > self.maxLimit) {
69
+ t.total = 0
70
+ t.consume = 0
71
+ }
72
+
73
+ t.total += 1
74
+ t.consume += time_consume
75
+
76
+ }
77
+
78
+ }
79
+
80
+ let last = self.route[c.method].get(c.routepath)
81
+
82
+ if (self.test) {
83
+
84
+ console.log(c.method, c.path, time_consume, 'ms')
85
+
86
+ console.log(c.method, c.path,'\n',
87
+ ` Count: ${last.total} Total: ${last.consume} ms `,
88
+ `Average: ${(last.consume/last.total).toFixed(2)} ms`
89
+ )
90
+ }
91
+
92
+ if (self.logfile) {
93
+
94
+ let log_text = `${c.method} - ${c.path} - count: ${last.total}, `
95
+ + `total: ${last.consume}ms, `
96
+ + `average: ${(last.consume/last.total).toFixed(2)}ms\n`
97
+
98
+ fs.writeFile(self.logfile, log_text, {flag: 'a+'}, err => {
99
+ if (self.test && err) {
100
+ console.error(err)
101
+ }
102
+ })
103
+ }
104
+
105
+ }
106
+
107
+ }
108
+
109
+ }
110
+
111
+ module.exports = Timing
@@ -0,0 +1,123 @@
1
+ 'use strict';
2
+
3
+ const fs = require('node:fs')
4
+ const crypto = require('node:crypto')
5
+
6
+ function extName(fname) {
7
+ let ind = fname.length - 2
8
+
9
+ while (ind > 0 && fname[ind] !== '.') {
10
+ ind -= 1
11
+ }
12
+
13
+ if (ind <= 0) return ''
14
+
15
+ return fname.substring(ind)
16
+ }
17
+
18
+ let fmtbits = (n) => {
19
+ return n < 10 ? `0${n}` : n
20
+ }
21
+
22
+ function makeName(filename = '') {
23
+ let tm = new Date()
24
+
25
+ let orgname = `${tm.getFullYear()}-${fmtbits(tm.getMonth()+1)}-${fmtbits(tm.getDate())}_`
26
+ + `${fmtbits(tm.getHours())}-${fmtbits(tm.getMinutes())}-${fmtbits(tm.getSeconds())}`
27
+ + `_${tm.getMilliseconds()}${parseInt(Math.random() * 1000) + 1}${parseInt(Math.random() * 100000) + 10000}`
28
+
29
+ if (filename) return (orgname + extName(filename))
30
+
31
+ return orgname
32
+ }
33
+
34
+ async function moveFile(target, filename = null) {
35
+ if (!this || !this.rawBody) return false
36
+
37
+ if (!filename) filename = makeName(this.filename || '')
38
+
39
+ let ds = ''
40
+ if (target[target.length-1] !== '/') ds = '/'
41
+
42
+ let pathfile = `${target}${ds}${filename}`
43
+
44
+ let fd = await new Promise((rv, rj) => {
45
+ fs.open(pathfile, 'w+', 0o644, (err, fd) => {
46
+ if (err) {
47
+ rj(err)
48
+ } else {
49
+ rv(fd)
50
+ }
51
+ })
52
+ })
53
+
54
+ return new Promise((rv, rj) => {
55
+ fs.write(fd, this.rawBody, this.start, this.length,
56
+ (err, bytesWritten, buffer) => {
57
+ if (err) {
58
+ rj(err)
59
+ } else {
60
+ rv(filename)
61
+ }
62
+ })
63
+ })
64
+ .finally(() => {
65
+ fs.close(fd, (err) => {})
66
+ })
67
+
68
+ }
69
+
70
+ function getFile(name, ind=0) {
71
+ if (!this || !this.files) return null
72
+
73
+ if (this.files[name] === undefined) {
74
+ return ind < 0 ? [] : null
75
+ }
76
+
77
+ if (ind >= this.files[name].length) {
78
+ return null
79
+ }
80
+
81
+ let flist = this.files[name]
82
+
83
+ if (ind < 0) {
84
+ for (let i = 0; i < flist.length; i++) {
85
+ if (flist[i].toFile === undefined) {
86
+ flist[i].rawBody = this.rawBody
87
+ flist[i].toFile = moveFile
88
+ }
89
+ }
90
+ return flist
91
+ }
92
+
93
+ if (flist[ind].toFile === undefined) {
94
+ flist[ind].rawBody = this.rawBody
95
+ flist[ind].toFile = moveFile
96
+ }
97
+
98
+ return flist[ind]
99
+ }
100
+
101
+
102
+ class ToFile {
103
+
104
+ constructor() {
105
+
106
+ }
107
+
108
+ mid() {
109
+ let self = this
110
+ return async (c, next) => {
111
+ if (!c.isUpload) {
112
+ return await next()
113
+ }
114
+
115
+ c.getFile = getFile
116
+ await next()
117
+ }
118
+
119
+ }
120
+
121
+ }
122
+
123
+ module.exports = ToFile
package/src/http1.js CHANGED
@@ -122,9 +122,8 @@ class Http1 {
122
122
  ctx.ip = remote_ip;
123
123
 
124
124
  ctx.port = req.socket.remotePort;
125
- ctx.request = req;
126
- ctx.response = res;
127
- ctx.reply = ctx.response;
125
+ ctx.req = req;
126
+ ctx.res = res;
128
127
 
129
128
  ctx.path = urlobj.path;
130
129
  ctx.query = urlobj.query;
@@ -147,7 +146,7 @@ class Http1 {
147
146
  mid() {
148
147
  let self = this;
149
148
 
150
- let noBodyMethods = {};
149
+ let noBodyMethods = Object.create(null);
151
150
 
152
151
  ['GET','OPTIONS','HEAD','TRACE'].forEach(a => {
153
152
  noBodyMethods[a] = true;
@@ -162,24 +161,24 @@ class Http1 {
162
161
  //客户端和服务端解析不会允许非法method
163
162
  if ( noBodyMethods[ctx.method] ) {
164
163
  //实际上这个回调函数不会执行,因为会立即触发end事件,此处可以保证非法的请求也可以提交数据。
165
- ctx.request.on('data', data => {
166
- ctx.response.statusCode = 400;
167
- ctx.response.end(self.config.badRequest);
168
- ctx.request.destroy();
164
+ ctx.req.on('data', data => {
165
+ ctx.res.statusCode = 400;
166
+ ctx.res.end(self.config.badRequest);
167
+ ctx.req.destroy();
169
168
  });
170
169
  } else {
171
170
  let bigBodyEnd = false;
172
171
  bodyBuffer = [];
173
- ctx.request.on('data', data => {
172
+ ctx.req.on('data', data => {
174
173
  bodylength += data.length;
175
174
  if (bodylength > ctx.maxBody) {
176
175
  if (bigBodyEnd) return;
177
176
  bigBodyEnd = true;
178
177
 
179
178
  bodyBuffer = null;
180
- ctx.response.statusCode = 413;
181
- ctx.response.end('', () => {
182
- ctx.request.destroy();
179
+ ctx.res.statusCode = 413;
180
+ ctx.res.end('', () => {
181
+ ctx.req.destroy();
183
182
  });
184
183
  return ;
185
184
  }
@@ -189,18 +188,18 @@ class Http1 {
189
188
 
190
189
  //若请求体太大,此时会进行destroy处理,触发close事件,但不会触发end。
191
190
  //通过记录resolved状态避免重复调用rv。
192
- ctx.request.on('close', () => {
191
+ ctx.req.on('close', () => {
193
192
  (!resolved) && rv();
194
193
  });
195
194
 
196
- ctx.request.on('end',() => {
195
+ ctx.req.on('end',() => {
197
196
  resolved = true;
198
197
  rv();
199
198
  });
200
199
 
201
200
  });
202
201
 
203
- if (!ctx.response.writable || ctx.response.writableEnded) {
202
+ if (!ctx.res.writable || ctx.res.writableEnded) {
204
203
  return;
205
204
  }
206
205
 
@@ -210,7 +209,7 @@ class Http1 {
210
209
  bodyBuffer = null;
211
210
  }
212
211
 
213
- await next();
212
+ await next(ctx);
214
213
  };
215
214
 
216
215
  }
package/src/http2.js CHANGED
@@ -126,8 +126,8 @@ class Httpt {
126
126
  ctx.ip = remote_ip;
127
127
  ctx.port = stream.session.socket.remotePort;
128
128
  ctx.stream = stream;
129
- ctx.reply = ctx.stream;
130
- ctx.request = ctx.stream;
129
+ ctx.res = ctx.stream;
130
+ ctx.req = ctx.stream;
131
131
 
132
132
  ctx.dataHeaders = {};
133
133
  ctx.headers = headers;
@@ -152,7 +152,7 @@ class Httpt {
152
152
 
153
153
  mid() {
154
154
  let self = this;
155
- let noBodyMethods = {};
155
+ let noBodyMethods = Object.create(null);
156
156
 
157
157
  ['GET','OPTIONS','HEAD','TRACE'].forEach(a => {
158
158
  noBodyMethods[a] = true;
@@ -164,7 +164,7 @@ class Httpt {
164
164
  let bodyBuffer;
165
165
 
166
166
  await new Promise((rv, rj) => {
167
- if ( noBodyMethods[ctx.method] ) {
167
+ if (noBodyMethods[ctx.method]) {
168
168
  ctx.stream.on('data', data => {
169
169
  ctx.stream.respond({':status' : '400'});
170
170
  ctx.stream.end(self.config.badRequest);
@@ -223,7 +223,7 @@ class Httpt {
223
223
  bodyBuffer = null;
224
224
  }
225
225
 
226
- await next();
226
+ await next(ctx);
227
227
  }
228
228
  //end func
229
229
  }
package/src/httpc.js CHANGED
@@ -132,10 +132,10 @@ Httpc.prototype.onRequest = function () {
132
132
  ctx.ip = remote_ip
133
133
 
134
134
  ctx.port = req.socket.remotePort
135
- ctx.request = req
136
- ctx.response = res
135
+ ctx.req = req
136
+ ctx.res = res
137
137
  ctx.stream = res
138
- ctx.reply = ctx.response
138
+
139
139
  ctx.headers = req.headers
140
140
 
141
141
  ctx.path = urlobj.path