@jayfong/x-server 1.34.2 → 1.34.4
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/_cjs/core/server.js +78 -46
- package/lib/core/server.js +77 -45
- package/package.json +1 -1
package/lib/_cjs/core/server.js
CHANGED
|
@@ -13,6 +13,8 @@ var _vtils = require("vtils");
|
|
|
13
13
|
|
|
14
14
|
var _http_method = require("./http_method");
|
|
15
15
|
|
|
16
|
+
var _http_error = require("./http_error");
|
|
17
|
+
|
|
16
18
|
var _x = require("../x");
|
|
17
19
|
|
|
18
20
|
class Server {
|
|
@@ -86,14 +88,65 @@ class Server {
|
|
|
86
88
|
}
|
|
87
89
|
|
|
88
90
|
async applyRoutes() {
|
|
91
|
+
const appUrl = _x.x.env.APP_URL.replace(/\/+$/, '');
|
|
92
|
+
|
|
93
|
+
const routeMap = (0, _vtils.keyBy)(this.routes, item => item.path);
|
|
94
|
+
|
|
95
|
+
const handleRoute = async (item, req, res) => {
|
|
96
|
+
const handlerOptions = item.handler.options;
|
|
97
|
+
const handlerMethod = handlerOptions.requestMethod || 'POST';
|
|
98
|
+
const isWS = handlerMethod === 'WS';
|
|
99
|
+
const url = `${appUrl}${// 结构:/test/sss?x=2
|
|
100
|
+
isWS ? res.url : req.url}`;
|
|
101
|
+
|
|
102
|
+
if (isWS) {
|
|
103
|
+
await item.handler.handle(undefined, {
|
|
104
|
+
url: url,
|
|
105
|
+
headers: res.headers,
|
|
106
|
+
setHeader: _vtils.noop,
|
|
107
|
+
redirect: _vtils.noop,
|
|
108
|
+
ws: req,
|
|
109
|
+
req: res,
|
|
110
|
+
res: {}
|
|
111
|
+
});
|
|
112
|
+
return;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
let files = {};
|
|
116
|
+
|
|
117
|
+
if (handlerMethod === 'FILE') {
|
|
118
|
+
const part = await req.file();
|
|
119
|
+
files = Object.keys(part.fields).reduce((res, name) => {
|
|
120
|
+
;
|
|
121
|
+
res[name] = (0, _vtils.castArray)(part.fields[name]).map(item => item.file ? item : item.value)[0];
|
|
122
|
+
return res;
|
|
123
|
+
}, {});
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
const data = await item.handler.handle({ // @ts-ignore
|
|
127
|
+
...req.params,
|
|
128
|
+
// @ts-ignore
|
|
129
|
+
...req.query,
|
|
130
|
+
// @ts-ignore
|
|
131
|
+
...req.body,
|
|
132
|
+
...files
|
|
133
|
+
}, {
|
|
134
|
+
url: url,
|
|
135
|
+
headers: req.headers,
|
|
136
|
+
setHeader: (k, v) => res.header(k, v),
|
|
137
|
+
redirect: url => res.redirect(url),
|
|
138
|
+
ws: undefined,
|
|
139
|
+
req: req,
|
|
140
|
+
res: res
|
|
141
|
+
});
|
|
142
|
+
return data;
|
|
143
|
+
};
|
|
144
|
+
|
|
89
145
|
for (const item of this.routes) {
|
|
90
146
|
const handlerOptions = item.handler.options;
|
|
91
147
|
const handlerMethod = handlerOptions.requestMethod || 'POST';
|
|
92
148
|
const isWS = handlerMethod === 'WS';
|
|
93
149
|
const serverMethod = isWS ? 'GET' : _http_method.HandlerMethodToHttpMethod[handlerMethod];
|
|
94
|
-
|
|
95
|
-
const appUrl = _x.x.env.APP_URL.replace(/\/+$/, '');
|
|
96
|
-
|
|
97
150
|
this.fastify.route({
|
|
98
151
|
method: serverMethod,
|
|
99
152
|
url: item.path,
|
|
@@ -101,54 +154,33 @@ class Server {
|
|
|
101
154
|
host: handlerOptions.requestHost
|
|
102
155
|
} : undefined,
|
|
103
156
|
websocket: isWS,
|
|
104
|
-
handler:
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
if (isWS) {
|
|
109
|
-
await item.handler.handle(undefined, {
|
|
110
|
-
url: url,
|
|
111
|
-
headers: res.headers,
|
|
112
|
-
setHeader: _vtils.noop,
|
|
113
|
-
redirect: _vtils.noop,
|
|
114
|
-
ws: req,
|
|
115
|
-
req: res,
|
|
116
|
-
res: {}
|
|
117
|
-
});
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
157
|
+
handler: (req, res) => handleRoute(item, req, res)
|
|
158
|
+
});
|
|
159
|
+
}
|
|
120
160
|
|
|
121
|
-
|
|
161
|
+
this.fastify.route({
|
|
162
|
+
method: 'POST',
|
|
163
|
+
url: '/@',
|
|
164
|
+
handler: async (req, res) => {
|
|
165
|
+
let requestPath = req.headers['x-path'] || '';
|
|
122
166
|
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return res;
|
|
129
|
-
}, {});
|
|
167
|
+
if (!requestPath.startsWith('/')) {
|
|
168
|
+
const [_requestPath, _time] = (0, _vtils.base64UrlDecode)((0, _vtils.rot13)(requestPath)).split('#');
|
|
169
|
+
|
|
170
|
+
if (!_time || Date.now() / 1000 - Number(_time) > 5 * 60) {
|
|
171
|
+
throw new _http_error.HttpError.Forbidden();
|
|
130
172
|
}
|
|
131
173
|
|
|
132
|
-
|
|
133
|
-
...req.params,
|
|
134
|
-
// @ts-ignore
|
|
135
|
-
...req.query,
|
|
136
|
-
// @ts-ignore
|
|
137
|
-
...req.body,
|
|
138
|
-
...files
|
|
139
|
-
}, {
|
|
140
|
-
url: url,
|
|
141
|
-
headers: req.headers,
|
|
142
|
-
setHeader: (k, v) => res.header(k, v),
|
|
143
|
-
redirect: url => res.redirect(url),
|
|
144
|
-
ws: undefined,
|
|
145
|
-
req: req,
|
|
146
|
-
res: res
|
|
147
|
-
});
|
|
148
|
-
return data;
|
|
174
|
+
requestPath = _requestPath;
|
|
149
175
|
}
|
|
150
|
-
|
|
151
|
-
|
|
176
|
+
|
|
177
|
+
if (!requestPath || !routeMap[requestPath]) {
|
|
178
|
+
throw new _http_error.HttpError.NotFound();
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
return handleRoute(routeMap[requestPath], req, res);
|
|
182
|
+
}
|
|
183
|
+
});
|
|
152
184
|
}
|
|
153
185
|
|
|
154
186
|
async startCrons() {
|
package/lib/core/server.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import Fastify from 'fastify';
|
|
2
|
-
import { castArray, noop } from 'vtils';
|
|
2
|
+
import { base64UrlDecode, castArray, keyBy, noop, rot13 } from 'vtils';
|
|
3
3
|
import { HandlerMethodToHttpMethod } from "./http_method";
|
|
4
|
+
import { HttpError } from "./http_error";
|
|
4
5
|
import { x } from "../x";
|
|
5
6
|
export class Server {
|
|
6
7
|
constructor(options) {
|
|
@@ -73,12 +74,64 @@ export class Server {
|
|
|
73
74
|
}
|
|
74
75
|
|
|
75
76
|
async applyRoutes() {
|
|
77
|
+
const appUrl = x.env.APP_URL.replace(/\/+$/, '');
|
|
78
|
+
const routeMap = keyBy(this.routes, item => item.path);
|
|
79
|
+
|
|
80
|
+
const handleRoute = async (item, req, res) => {
|
|
81
|
+
const handlerOptions = item.handler.options;
|
|
82
|
+
const handlerMethod = handlerOptions.requestMethod || 'POST';
|
|
83
|
+
const isWS = handlerMethod === 'WS';
|
|
84
|
+
const url = `${appUrl}${// 结构:/test/sss?x=2
|
|
85
|
+
isWS ? res.url : req.url}`;
|
|
86
|
+
|
|
87
|
+
if (isWS) {
|
|
88
|
+
await item.handler.handle(undefined, {
|
|
89
|
+
url: url,
|
|
90
|
+
headers: res.headers,
|
|
91
|
+
setHeader: noop,
|
|
92
|
+
redirect: noop,
|
|
93
|
+
ws: req,
|
|
94
|
+
req: res,
|
|
95
|
+
res: {}
|
|
96
|
+
});
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
let files = {};
|
|
101
|
+
|
|
102
|
+
if (handlerMethod === 'FILE') {
|
|
103
|
+
const part = await req.file();
|
|
104
|
+
files = Object.keys(part.fields).reduce((res, name) => {
|
|
105
|
+
;
|
|
106
|
+
res[name] = castArray(part.fields[name]).map(item => item.file ? item : item.value)[0];
|
|
107
|
+
return res;
|
|
108
|
+
}, {});
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const data = await item.handler.handle({ // @ts-ignore
|
|
112
|
+
...req.params,
|
|
113
|
+
// @ts-ignore
|
|
114
|
+
...req.query,
|
|
115
|
+
// @ts-ignore
|
|
116
|
+
...req.body,
|
|
117
|
+
...files
|
|
118
|
+
}, {
|
|
119
|
+
url: url,
|
|
120
|
+
headers: req.headers,
|
|
121
|
+
setHeader: (k, v) => res.header(k, v),
|
|
122
|
+
redirect: url => res.redirect(url),
|
|
123
|
+
ws: undefined,
|
|
124
|
+
req: req,
|
|
125
|
+
res: res
|
|
126
|
+
});
|
|
127
|
+
return data;
|
|
128
|
+
};
|
|
129
|
+
|
|
76
130
|
for (const item of this.routes) {
|
|
77
131
|
const handlerOptions = item.handler.options;
|
|
78
132
|
const handlerMethod = handlerOptions.requestMethod || 'POST';
|
|
79
133
|
const isWS = handlerMethod === 'WS';
|
|
80
134
|
const serverMethod = isWS ? 'GET' : HandlerMethodToHttpMethod[handlerMethod];
|
|
81
|
-
const appUrl = x.env.APP_URL.replace(/\/+$/, '');
|
|
82
135
|
this.fastify.route({
|
|
83
136
|
method: serverMethod,
|
|
84
137
|
url: item.path,
|
|
@@ -86,54 +139,33 @@ export class Server {
|
|
|
86
139
|
host: handlerOptions.requestHost
|
|
87
140
|
} : undefined,
|
|
88
141
|
websocket: isWS,
|
|
89
|
-
handler:
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
redirect: noop,
|
|
99
|
-
ws: req,
|
|
100
|
-
req: res,
|
|
101
|
-
res: {}
|
|
102
|
-
});
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
142
|
+
handler: (req, res) => handleRoute(item, req, res)
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
this.fastify.route({
|
|
147
|
+
method: 'POST',
|
|
148
|
+
url: '/@',
|
|
149
|
+
handler: async (req, res) => {
|
|
150
|
+
let requestPath = req.headers['x-path'] || '';
|
|
105
151
|
|
|
106
|
-
|
|
152
|
+
if (!requestPath.startsWith('/')) {
|
|
153
|
+
const [_requestPath, _time] = base64UrlDecode(rot13(requestPath)).split('#');
|
|
107
154
|
|
|
108
|
-
if (
|
|
109
|
-
|
|
110
|
-
files = Object.keys(part.fields).reduce((res, name) => {
|
|
111
|
-
;
|
|
112
|
-
res[name] = castArray(part.fields[name]).map(item => item.file ? item : item.value)[0];
|
|
113
|
-
return res;
|
|
114
|
-
}, {});
|
|
155
|
+
if (!_time || Date.now() / 1000 - Number(_time) > 5 * 60) {
|
|
156
|
+
throw new HttpError.Forbidden();
|
|
115
157
|
}
|
|
116
158
|
|
|
117
|
-
|
|
118
|
-
...req.params,
|
|
119
|
-
// @ts-ignore
|
|
120
|
-
...req.query,
|
|
121
|
-
// @ts-ignore
|
|
122
|
-
...req.body,
|
|
123
|
-
...files
|
|
124
|
-
}, {
|
|
125
|
-
url: url,
|
|
126
|
-
headers: req.headers,
|
|
127
|
-
setHeader: (k, v) => res.header(k, v),
|
|
128
|
-
redirect: url => res.redirect(url),
|
|
129
|
-
ws: undefined,
|
|
130
|
-
req: req,
|
|
131
|
-
res: res
|
|
132
|
-
});
|
|
133
|
-
return data;
|
|
159
|
+
requestPath = _requestPath;
|
|
134
160
|
}
|
|
135
|
-
|
|
136
|
-
|
|
161
|
+
|
|
162
|
+
if (!requestPath || !routeMap[requestPath]) {
|
|
163
|
+
throw new HttpError.NotFound();
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
return handleRoute(routeMap[requestPath], req, res);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
137
169
|
}
|
|
138
170
|
|
|
139
171
|
async startCrons() {
|