@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.
@@ -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: async (req, res) => {
105
- const url = `${appUrl}${// 结构:/test/sss?x=2
106
- isWS ? res.url : req.url}`;
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
- let files = {};
161
+ this.fastify.route({
162
+ method: 'POST',
163
+ url: '/@',
164
+ handler: async (req, res) => {
165
+ let requestPath = req.headers['x-path'] || '';
122
166
 
123
- if (handlerMethod === 'FILE') {
124
- const part = await req.file();
125
- files = Object.keys(part.fields).reduce((res, name) => {
126
- ;
127
- res[name] = (0, _vtils.castArray)(part.fields[name]).map(item => item.file ? item : item.value)[0];
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
- const data = await item.handler.handle({ // @ts-ignore
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() {
@@ -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: async (req, res) => {
90
- const url = `${appUrl}${// 结构:/test/sss?x=2
91
- isWS ? res.url : req.url}`;
92
-
93
- if (isWS) {
94
- await item.handler.handle(undefined, {
95
- url: url,
96
- headers: res.headers,
97
- setHeader: noop,
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
- let files = {};
152
+ if (!requestPath.startsWith('/')) {
153
+ const [_requestPath, _time] = base64UrlDecode(rot13(requestPath)).split('#');
107
154
 
108
- if (handlerMethod === 'FILE') {
109
- const part = await req.file();
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
- const data = await item.handler.handle({ // @ts-ignore
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() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jayfong/x-server",
3
- "version": "1.34.2",
3
+ "version": "1.34.4",
4
4
  "license": "ISC",
5
5
  "sideEffects": false,
6
6
  "main": "lib/_cjs/index.js",