birdpack 1.0.2 → 1.0.3

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/lib/core.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const tools = require('./tools');
2
+ const powered = require('./powered');
2
3
  const fs = require('fs');
3
4
  const fileType = require('./fileType');
4
5
 
@@ -9,10 +10,12 @@ module.exports = class{
9
10
  buffers = []
10
11
  body = {}
11
12
  host = ''
12
- url = ''
13
+ path = ''
13
14
  query = {}
14
15
  method = ''
16
+ ip = ''
15
17
  callrouter = ()=>{}
18
+ log = ()=>{}
16
19
  params = {}
17
20
  constructor({req, res}){
18
21
  this.req = req;
@@ -60,8 +63,22 @@ module.exports = class{
60
63
  return false;
61
64
  }
62
65
 
63
- const findHost = this.req.headers.host.indexOf(':');
64
- this.host = findHost === -1 ? this.req.headers.host : this.req.headers.host.slice(0, findHost);
66
+ let ipcf = this.get('cf-connecting-ip');
67
+ let ipx = this.get('x-forwarded-for');
68
+ if(ipcf){
69
+ this.ip = ipcf;
70
+ }else if(ipx){
71
+ this.ip = ipx.split(',')[0];
72
+ }else{
73
+ this.ip = this.res.socket.remoteAddress;
74
+ }
75
+
76
+ if(this.res.socket.servername){
77
+ this.host = this.res.socket.servername;
78
+ }else{
79
+ const findHost = this.req.headers.host.indexOf(':');
80
+ this.host = findHost === -1 ? this.req.headers.host : this.req.headers.host.slice(0, findHost);
81
+ }
65
82
 
66
83
  this.method = this.req.method.toLowerCase();
67
84
 
@@ -96,6 +113,9 @@ module.exports = class{
96
113
  }
97
114
  return true;
98
115
  }
116
+ traffic(f){
117
+ this.log = f;
118
+ }
99
119
  router(call){
100
120
  this.callrouter = call;
101
121
  }
@@ -169,12 +189,14 @@ module.exports = class{
169
189
  }
170
190
 
171
191
  writeHead(){
172
- this.header['x-powered-by'] = `R938`;
192
+ this.header['x-powered-by'] = powered.by;
173
193
  if(this.res.writable){
174
- this.res.writeHead(this.status ? this.status : 200, this.header);
194
+ this.status = this.status ? this.status : 200;
195
+ this.res.writeHead(this.status, this.header);
175
196
  }else if(this.req.destroyed){
176
197
  this.req.destroy();
177
198
  }
199
+ this.log();
178
200
  return this;
179
201
  }
180
202
  write(data, callback){
package/lib/method.js ADDED
@@ -0,0 +1,153 @@
1
+ const tools = require('./tools');
2
+ const METHOD = ['get','post','put','patch','delete','head','options'];
3
+ const fs = require('fs');
4
+
5
+ module.exports = {
6
+ METHOD,
7
+ basic:(app, use, {domain, next})=>{
8
+ for(let x of METHOD){
9
+ use[x] = (url, callback)=>{
10
+ app.set({
11
+ domain,
12
+ method:x,
13
+ url,
14
+ next,
15
+ callback:app.setCall(callback)
16
+ });
17
+ return use;
18
+ }
19
+ }
20
+ },
21
+ directory:(use)=>{
22
+ return (dir, {path, callback, error})=>{
23
+ if(typeof path !== 'string'){
24
+ path = '/';
25
+ }else if(path[path.length-1] != '/'){
26
+ path += '/';
27
+ }
28
+
29
+ let getPath = path + '*';
30
+ if(dir != '' && dir[dir.length-1] != '/'){
31
+ dir += '/';
32
+ }
33
+
34
+ if(typeof callback !== 'function'){
35
+ callback = (req, {load, file})=>{
36
+ req.file(load, {
37
+ error:(code, text)=>{
38
+ error(req, code, text);
39
+ }
40
+ });
41
+ }
42
+ }
43
+ if(typeof error !== 'function'){
44
+ error = (req, code, text)=>{
45
+ req.code(code).send(text);
46
+ }
47
+ }
48
+
49
+ use.get(getPath, (req)=>{
50
+ let searchPath = req.path.search(path);
51
+ let checkPath = req.path.substr(searchPath + path.length);
52
+ if(checkPath != ''){
53
+ let file = tools.checkPath(checkPath);
54
+ if(file !== false){
55
+ let load = `${dir}${file}`;
56
+
57
+ return callback(req, {load, file});
58
+ }
59
+ }
60
+
61
+ error(req, 404, 'File not found.');
62
+ });
63
+ return this;
64
+ }
65
+ },
66
+ websocket:(app, use, domain)=>{
67
+ return (url, a, b, c)=>{
68
+ let typeA = typeof a == 'function';
69
+ let typeB = typeof b == 'function';
70
+ let typeC = typeof c == 'function';
71
+ let callback;
72
+
73
+ if(typeA && typeB && typeC){
74
+ callback = async(core, code) => {
75
+ if(code == 'start'){
76
+ let check = await a(core, core.body);
77
+
78
+ if(check !== true){
79
+ core.stop();
80
+ }
81
+ }else if(code == 'data'){
82
+ await b(core, core.body);
83
+ }else if(code == 'close'){
84
+ await c(core, core.body);
85
+ }
86
+ };
87
+ }else if(typeA){
88
+ callback = a;
89
+ }
90
+
91
+ callback.users = {
92
+ member:{},
93
+ length:0,
94
+ };
95
+
96
+ app.setUpgrade({
97
+ domain,
98
+ url,
99
+ callback: app.setCall(callback)
100
+ });
101
+ return use;
102
+ };
103
+ },
104
+ routes:(use)=>{
105
+ return (dir)=>{
106
+ if(fs.lstatSync(dir).isDirectory()){
107
+ let path = `${dir}/`;
108
+ let list = {};
109
+ fs.readdirSync(path).forEach((file)=>{
110
+ if(fs.existsSync(path + file)){
111
+ let ext = file.split('.').pop();
112
+ if(ext == 'js'){
113
+ let pathFile = path + file;
114
+ list[file.slice(0,-3)] = require(pathFile);
115
+ }
116
+ }
117
+ });
118
+
119
+ for(let x in list){
120
+ let db = x.split('@');
121
+ let method = "get";
122
+ let path = '';
123
+
124
+ if(db.length == 1){
125
+ path = db[0];
126
+ }else if(db.length == 2){
127
+ method = db[0];
128
+ path = db[1];
129
+ }else{
130
+ break;
131
+ }
132
+
133
+ path = path.replace(/[\-\$\"]/g,(a)=>{
134
+ let list={
135
+ '-':'/',
136
+ '$':':'
137
+ };
138
+ if(list.hasOwnProperty(a)){
139
+ return list[a];
140
+ }else{
141
+ return '';
142
+ }
143
+ });
144
+
145
+ if(use[method]){
146
+ use[method](`/${path}`, list[x]);
147
+ }
148
+ }
149
+ }
150
+ return use;
151
+ };
152
+ },
153
+ };
package/lib/powered.js ADDED
@@ -0,0 +1,18 @@
1
+ let package = {};
2
+
3
+ try{
4
+ package = require(`${__dirname}/../package.json`);
5
+ }catch(e){
6
+ console.log('Not have package.json');
7
+ }
8
+
9
+ let version = package.version || '1.0.0';
10
+ let author = package.author || 'R938';
11
+ let name = package.name || 'R938';
12
+
13
+ module.exports = {
14
+ name,
15
+ by:`${author}/${version}`,
16
+ version,
17
+ author
18
+ };
package/lib/server.js CHANGED
@@ -1,6 +1,8 @@
1
+ const fs = require('fs');
1
2
  const core = require('./core');
2
3
  const websocket = require('./websocket');
3
- const R938_METHOD = ['get','post','put','patch','delete','head','options'];
4
+ const powered = require('./powered');
5
+ const methodPlugin = require('./method');
4
6
 
5
7
  module.exports = class{
6
8
  mapws = {}
@@ -9,12 +11,33 @@ module.exports = class{
9
11
  constructor(opt){
10
12
  this.opt = opt || {};
11
13
 
12
- console.log(this.powered());
14
+ this.powered();
15
+ this.dev();
13
16
 
14
17
  this.argv();
15
18
  this.setupMethod();
16
19
  this.setupSSL();
17
20
  }
21
+ dev(){
22
+ if(typeof this.opt.log !== 'string'){
23
+ this.opt.log = 'console';
24
+ }
25
+
26
+ if(this.opt.log == 'console'){
27
+ this.log = (status, text)=>{
28
+ let out = `[${status}] - ${text}`;
29
+ console.log(out);
30
+ }
31
+ }else if(this.opt.log == 'file' && typeof this.opt.logFile == 'string'){
32
+ let file = fs.createWriteStream(this.opt.logFile, { flags: 'a' });
33
+ this.log = (status, text)=>{
34
+ let out = `[${status}] - ${text}`;
35
+ file.write(`${out}\n`);
36
+ }
37
+ }else{
38
+ this.log = ()=>{};
39
+ }
40
+ }
18
41
  argv(){
19
42
  let cmd = {
20
43
  '-u':'use',
@@ -32,19 +55,16 @@ module.exports = class{
32
55
  }
33
56
  }
34
57
  setupMethod(){
35
- for(let x of R938_METHOD){
36
- this[x] = (url, callback)=>{
37
- this.set({
38
- domain:'*',
39
- method:x,
40
- url,
41
- callback:this.setCall(callback)
42
- });
43
- return this;
44
- }
45
- }
58
+ methodPlugin.basic(this, this, {domain:'*'});
59
+ this.routes = methodPlugin.routes(this);
60
+ this.directory = methodPlugin.directory(this);
61
+ this.websocket = methodPlugin.websocket(this, this, '*');
46
62
  }
47
63
  setupSSL(){
64
+ if(this.opt.use !== 'https'){
65
+ return false;
66
+ }
67
+
48
68
  const tls = require('tls');
49
69
  const sslSecure = [];
50
70
  const sslDomain = {};
@@ -98,7 +118,10 @@ module.exports = class{
98
118
  this.server = createServer(options, (req, res)=>{
99
119
  let cc = new core({req, res});
100
120
 
101
- cc.router(()=>{
121
+ cc.traffic(()=>{
122
+ this.traffic(cc);
123
+ });
124
+ cc.router(()=>{
102
125
  let call = this.maps[cc.host];
103
126
  if(!call && this.maps['*']){
104
127
  call = this.maps['*']
@@ -174,6 +197,10 @@ module.exports = class{
174
197
  });
175
198
  this.server.on('upgrade', (req, socket, head) => {
176
199
  const ws = new websocket({req, socket, head});
200
+ ws.traffic(()=>{
201
+ this.traffic(ws);
202
+ });
203
+
177
204
  let call = this.mapws[ws.host];
178
205
  if(!call && this.mapws['*']){
179
206
  call = this.mapws['*']
@@ -181,6 +208,7 @@ module.exports = class{
181
208
 
182
209
  if(call && call.hasOwnProperty(ws.path)){
183
210
  call = call[ws.path].callback;
211
+ this.traffic(ws);
184
212
 
185
213
  const run = this.getCall(call);
186
214
 
@@ -194,6 +222,8 @@ module.exports = class{
194
222
  }
195
223
  listen(port, host){
196
224
  if(this.create()){
225
+ this.logServer('server', `Welcome to Server BirdPack by R938`);
226
+
197
227
  let domain = {};
198
228
  for(let x in this.maps){
199
229
  domain[x] = 1;
@@ -202,21 +232,25 @@ module.exports = class{
202
232
  domain[x] = 1;
203
233
  }
204
234
  for(let x in domain){
205
- this.log('domain', `${x}`);
235
+ this.logServer('server', `Use domian ${x}`);
206
236
  }
207
237
 
238
+ this.logServer('server', `The server is collecting logs via (${this.opt.log})`);
208
239
  this.server.listen(port || this.opt.port || process.env.PORT || 3000, host, ()=>{
209
- this.log('server', `Started on server(${this.opt.use}) port(${this.server._connectionKey.split(':').pop()})`);
240
+ this.logServer('server', `Started on server(${this.opt.use}) port(${this.server._connectionKey.split(':').pop()})`);
210
241
  });
211
242
  }
212
243
  }
213
-
214
- log(status, text){
244
+ logServer(status, text){
215
245
  let out = `[${status}] - ${text}`;
216
246
  console.log(out);
217
247
  }
248
+ traffic(c){
249
+ this.log('client',`${c.status} ${c.method} ${c.path} ${c.ip} ${c.get('user-agent')}`);
250
+ }
251
+
218
252
  powered(){
219
- return [
253
+ console.log([
220
254
  `\x1b[32m`,
221
255
  ` __ _________`,
222
256
  ` |__| |_______ \\`,
@@ -224,12 +258,12 @@ module.exports = class{
224
258
  ` | | \\ \\`,
225
259
  ` | |__________/ /`,
226
260
  ` | ______ __/`,
227
- ` | | | | \x1b[33m | \x1b[36mBirdPack Framework\x1b[33m | \x1b[32m`,
228
- ` | | | | \x1b[33m | \x1b[0mR938 Service\x1b[33m | \x1b[32m`,
229
- ` |__| |__| \x1b[33m | \x1b[0mVersion: 1.0.0\x1b[33m | \x1b[0m`,
261
+ ` | | | | \x1b[33m | \x1b[36mFramework: ${powered.name}\x1b[32m`,
262
+ ` | | | | \x1b[33m | \x1b[0mAuthor: ${powered.author}\x1b[32m`,
263
+ ` |__| |__| \x1b[33m | \x1b[0mVersion: ${powered.version}\x1b[0m`,
230
264
  `____________________________________________`,
231
265
  '',
232
- ].join('\n');
266
+ ].join('\n'));
233
267
  }
234
268
 
235
269
  domain(domain){
@@ -238,72 +272,19 @@ module.exports = class{
238
272
  }
239
273
 
240
274
  let config = {
241
- websocket:(url, a, b, c)=>{
242
- let typeA = typeof a == 'function';
243
- let typeB = typeof b == 'function';
244
- let typeC = typeof c == 'function';
245
- let callback;
246
-
247
- if(typeA && typeB && typeC){
248
- callback = async(core, code) => {
249
- if(code == 'start'){
250
- let check = await a(core, core.body);
251
-
252
- if(check !== true){
253
- core.stop();
254
- }
255
- }else if(code == 'data'){
256
- await b(core, core.body);
257
- }else if(code == 'close'){
258
- await c(core, core.body);
259
- }
260
- };
261
- }else if(typeA){
262
- callback = a;
263
- }
264
-
265
- callback.users = {
266
- member:{},
267
- length:0,
268
- };
269
-
270
- this.setUpgrade({
271
- domain,
272
- url,
273
- callback: this.setCall(callback)
274
- });
275
- return config;
276
- },
277
275
  next:(n)=>{
278
- let next = {};
279
- for(let x of R938_METHOD){
280
- next[x] = (url, callback)=>{
281
- this.set({
282
- domain,
283
- method:x,
284
- url,
285
- next:this.setCall(n),
286
- callback:this.setCall(callback)
287
- });
288
- return next;
289
- }
290
- }
276
+ let next = {};
277
+ methodPlugin.basic(this, next, {domain, next:this.setCall(n)});
278
+ next.routes = methodPlugin.routes(next);
279
+ next.directory = methodPlugin.directory(next);
291
280
 
292
281
  return next;
293
282
  }
294
283
  }
295
-
296
- for(let x of R938_METHOD){
297
- config[x] = (url, callback)=>{
298
- this.set({
299
- domain,
300
- method:x,
301
- url,
302
- callback:this.setCall(callback)
303
- });
304
- return config;
305
- }
306
- }
284
+ methodPlugin.basic(this, config, {domain});
285
+ config.routes = methodPlugin.routes(config);
286
+ config.directory = methodPlugin.directory(config);
287
+ config.websocket = methodPlugin.websocket(this, config, domain);
307
288
 
308
289
  return config;
309
290
  }
@@ -312,7 +293,7 @@ module.exports = class{
312
293
  domain = '*';
313
294
  }
314
295
 
315
- if(typeof method != 'string' || !R938_METHOD.includes(method)){
296
+ if(typeof method != 'string' || !methodPlugin.METHOD.includes(method)){
316
297
  method = 'get';
317
298
  }
318
299
  method = method.toLowerCase();
@@ -386,41 +367,5 @@ module.exports = class{
386
367
  return this.calls[id];
387
368
  }
388
369
  return ()=>{};
389
- }
390
- websocket(url, a, b, c){
391
- let typeA = typeof a == 'function';
392
- let typeB = typeof b == 'function';
393
- let typeC = typeof c == 'function';
394
- let callback;
395
-
396
- if(typeA && typeB && typeC){
397
- callback = async(core, code) => {
398
- if(code == 'start'){
399
- let check = await a(core, core.body);
400
-
401
- if(check !== true){
402
- core.stop();
403
- }
404
- }else if(code == 'data'){
405
- await b(core, core.body);
406
- }else if(code == 'close'){
407
- await c(core, core.body);
408
- }
409
- };
410
- }else if(typeA){
411
- callback = a;
412
- }
413
-
414
- callback.users = {
415
- member:{},
416
- length:0,
417
- };
418
-
419
- this.setUpgrade({
420
- domain: '*',
421
- url,
422
- callback: this.setCall(callback)
423
- });
424
- return this;
425
370
  }
426
371
  }
package/lib/tools.js CHANGED
@@ -324,7 +324,14 @@ const tools = {
324
324
  .toString('base64')
325
325
  .replace(/[^a-zA-Z0-9]/g, '')
326
326
  .slice(0, 64);
327
- }
327
+ },
328
+ checkPath:(name)=>{
329
+ try{
330
+ name = decodeURIComponent(name);
331
+ return name.replace(/(\.\.)|[\[\n\r\t\*\?\"\<\>\|]/,'') == name ? name : false;
332
+ }catch(e){}
333
+ return false;
334
+ },
328
335
  };
329
336
 
330
337
  module.exports = tools;
package/lib/websocket.js CHANGED
@@ -1,4 +1,5 @@
1
1
  const tools = require('./tools');
2
+ const powered = require('./powered');
2
3
 
3
4
  module.exports = class{
4
5
  status = 0
@@ -6,10 +7,12 @@ module.exports = class{
6
7
  cookie = {}
7
8
  body = {}
8
9
  host = ''
9
- url = ''
10
+ path = ''
10
11
  query = {}
11
12
  method = ''
13
+ ip = ''
12
14
  callback = ()=>{}
15
+ log = ()=>{}
13
16
  constructor({req, socket, head}){
14
17
  this.req = req;
15
18
  this.socket = socket;
@@ -40,8 +43,22 @@ module.exports = class{
40
43
  return false;
41
44
  }
42
45
 
43
- const findHost = this.req.headers.host.indexOf(':');
44
- this.host = findHost === -1 ? this.req.headers.host : this.req.headers.host.slice(0, findHost);
46
+ let ipcf = this.get('cf-connecting-ip');
47
+ let ipx = this.get('x-forwarded-for');
48
+ if(ipcf){
49
+ this.ip = ipcf;
50
+ }else if(ipx){
51
+ this.ip = ipx.split(',')[0];
52
+ }else{
53
+ this.ip = this.socket.remoteAddress;
54
+ }
55
+
56
+ if(this.socket.servername){
57
+ this.host = this.socket.servername;
58
+ }else{
59
+ const findHost = this.req.headers.host.indexOf(':');
60
+ this.host = findHost === -1 ? this.req.headers.host : this.req.headers.host.slice(0, findHost);
61
+ }
45
62
 
46
63
  this.method = this.req.headers.upgrade === 'websocket' ? 'websocket' : this.req.method.toLowerCase();
47
64
 
@@ -79,6 +96,9 @@ module.exports = class{
79
96
  update(call){
80
97
  this.callback = call;
81
98
  }
99
+ traffic(f){
100
+ this.log = f;
101
+ }
82
102
 
83
103
  code(status){
84
104
  this.status = status;
@@ -145,13 +165,15 @@ module.exports = class{
145
165
  }
146
166
 
147
167
  writeHead(){
148
- this.header['x-powered-by'] = `R938`;
168
+ this.header['x-powered-by'] = powered.by;
149
169
 
150
170
  const head = tools.head2line(this.header);
151
171
  const statusLine = `HTTP/1.1 ${this.status} ${tools.statusText(this.status)}`;
152
172
  const headLine = `${statusLine}\r\n${head}\r\n\r\n`;
153
173
  this.write(Buffer.from(headLine));
154
174
 
175
+ this.log();
176
+
155
177
  return this;
156
178
  }
157
179
  write(data, callback){
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name":"birdpack",
3
3
  "description": "BirdPack web framework is a tool for web server via TCP HTTP supporting websocket focusing on speed.",
4
4
  "author":"R938",
5
- "license":"r938",
6
- "version":"1.0.2",
5
+ "license":"R938",
6
+ "version":"1.0.3",
7
7
  "main": "index.js"
8
8
  }