@3-/srv 0.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 (4) hide show
  1. package/README.md +41 -0
  2. package/br.js +37 -0
  3. package/index.js +116 -0
  4. package/package.json +1 -0
package/README.md ADDED
@@ -0,0 +1,41 @@
1
+ [‼️]: ✏️README.mdt
2
+
3
+ # @3-/srv
4
+
5
+ 返回值
6
+
7
+ 如果函数,会被传入 res ,可以 res.writeStatus(status).end(r)
8
+
9
+ 如果不是 undefined ,会被 msgpack pack
10
+
11
+ post,put
12
+
13
+ 如果 content_type.endsWith '/json'
14
+
15
+ body 如果 length > 1
16
+
17
+ 会被 json parse
18
+
19
+ 如果是一个数组 会 f.apply opt, body
20
+
21
+ 否则会 f.call opt, body
22
+
23
+ 否则如果 body 有的长度 f.call opt, body
24
+
25
+ [test/main.coffee](./test/main.coffee) :
26
+
27
+ ```coffee
28
+ #!/usr/bin/env coffee
29
+ ```
30
+
31
+ output :
32
+
33
+ ```
34
+ /test
35
+ → http://127.0.0.1:3223
36
+ uWS.App {}
37
+ post test
38
+ post test
39
+ post test
40
+ post test
41
+ ```
package/br.js ADDED
@@ -0,0 +1,37 @@
1
+ var brCompress;
2
+
3
+ import {
4
+ brotliCompress
5
+ } from 'zlib';
6
+
7
+ import {
8
+ promisify
9
+ } from 'util';
10
+
11
+ brCompress = promisify(brotliCompress);
12
+
13
+ export default async(res, status, accept_encoding, content_type, bin) => {
14
+ var br, content_encoding, length;
15
+ ({length} = bin);
16
+ if (bin.length > 512) {
17
+ if (accept_encoding != null ? accept_encoding.includes('br') : void 0) {
18
+ br = (await brCompress(bin));
19
+ if ((20 + br.length) < length) { // 因为 Content-Encoding: br 是 20 字节
20
+ content_encoding = 'br';
21
+ bin = br;
22
+ }
23
+ }
24
+ }
25
+ if (!res.aborted) {
26
+ res.cork(() => {
27
+ res.writeStatus(status);
28
+ if (content_type) {
29
+ res.writeHeader('Content-Type', content_type);
30
+ }
31
+ if (content_encoding) {
32
+ res.writeHeader('Content-Encoding', content_encoding);
33
+ }
34
+ res.end(br);
35
+ });
36
+ }
37
+ };
package/index.js ADDED
@@ -0,0 +1,116 @@
1
+ var bind;
2
+
3
+ import uWebSockets from 'uWebSockets';
4
+
5
+ import {
6
+ pack
7
+ } from '@3-/msgpack';
8
+
9
+ import br from './br.js';
10
+
11
+ import {
12
+ Cookie
13
+ } from 'tough-cookie';
14
+
15
+ ({PORT} = process.env);
16
+
17
+ export var OK = '200';
18
+
19
+ export var NOT_FOUND = '404';
20
+
21
+ export var PORT = +PORT;
22
+
23
+ bind = (ws, name, func) => {
24
+ console.log('/' + name);
25
+ ws.any('/' + name, async(res, req) => {
26
+ var accept_encoding, accept_language, body, content_type, cookie, err, method, opt, r, res_content_type, status, url;
27
+ method = req.getMethod();
28
+ url = req.getUrl();
29
+ content_type = req.getHeader('content-type');
30
+ accept_language = req.getHeader('accept-language');
31
+ cookie = req.getHeader('cookie');
32
+ if (cookie) {
33
+ cookie = Cookie.parse(cookie);
34
+ }
35
+ accept_encoding = req.getHeader('accept-encoding');
36
+ opt = {content_type, accept_language, method, url, cookie};
37
+ if (accept_encoding) {
38
+ opt.accept_encoding = accept_encoding.split(',').map((i) => {
39
+ return i.trim();
40
+ });
41
+ }
42
+ try {
43
+ switch (method) {
44
+ case 'post':
45
+ case 'put':
46
+ res.onAborted(() => {
47
+ res.aborted = true;
48
+ });
49
+ body = (await new Promise((resolve) => {
50
+ var li;
51
+ li = [];
52
+ res.onData((buf, isLast) => {
53
+ if (buf.byteLength > 0) {
54
+ li.push(Buffer.from(buf));
55
+ }
56
+ if (isLast) {
57
+ if (li.length > 0) {
58
+ li = Buffer.concat(li);
59
+ }
60
+ resolve(li);
61
+ }
62
+ });
63
+ }));
64
+ }
65
+ if (body && body.length > 0) {
66
+ if (content_type.endsWith('/json')) {
67
+ body = JSON.parse(body);
68
+ if (Array.isArray(body)) {
69
+ r = (await func.apply(opt, body));
70
+ } else {
71
+ r = (await func.call(opt, body));
72
+ }
73
+ } else {
74
+ r = (await func.call(opt, body));
75
+ }
76
+ } else {
77
+ r = (await func.call(opt));
78
+ }
79
+ if (r instanceof Function) {
80
+ await r(res);
81
+ } else {
82
+ if (r === void 0) {
83
+ r = '';
84
+ } else {
85
+ r = pack(r);
86
+ res_content_type = 'm';
87
+ }
88
+ }
89
+ status = OK;
90
+ } catch (error) {
91
+ err = error;
92
+ status = '500';
93
+ r = '' + err;
94
+ console.error(method, url, err);
95
+ }
96
+ console.log(status, method, name);
97
+ br(res, status, accept_encoding, res_content_type, r);
98
+ });
99
+ };
100
+
101
+ export default (route) => {
102
+ var f, name, ref, ws, x;
103
+ ws = uWebSockets.App({});
104
+ ref = Object.entries(route);
105
+ for (x of ref) {
106
+ [name, f] = x;
107
+ bind(ws, name, f);
108
+ }
109
+ return ws.any('/*', (res, req) => {
110
+ console.log(NOT_FOUND, req.getMethod(), req.getUrl());
111
+ // https://unetworking.github.io/uWebSockets.js/generated/interfaces/HttpRequest.html#getMethod
112
+ res.writeStatus(NOT_FOUND).end('');
113
+ }).listen(PORT, () => {
114
+ console.log('→ http://127.0.0.1:' + PORT);
115
+ });
116
+ };
package/package.json ADDED
@@ -0,0 +1 @@
1
+ {"name":"@3-/srv","version":"0.0.1","repository":"https://github.com/3TiSite/node.git","homepage":"https://github.com/3TiSite/node/tree/main/srv","author":"3Ti.Site@gmail.com","license":"Apache-2.0","exports":{".":"./index.js","./*":"./*"},"files":["./*"],"type":"module","dependencies":{"@3-/msgpack":"^0.0.2","tough-cookie":"^4.1.3","uWebSockets":"^0.0.1"}}