@jnode/server 1.0.6 → 2.0.0
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/README.md +394 -34
- package/package.json +2 -2
- package/src/handlers.js +246 -0
- package/src/index.js +28 -8
- package/src/routers.js +210 -0
- package/src/server.js +203 -42
- package/src/error.js +0 -32
- package/src/final.js +0 -129
- package/src/handle.js +0 -88
- package/src/map.js +0 -50
package/src/server.js
CHANGED
|
@@ -1,55 +1,216 @@
|
|
|
1
1
|
/*
|
|
2
|
-
|
|
2
|
+
@jnode/server/server.js
|
|
3
|
+
v2
|
|
3
4
|
|
|
4
5
|
Simple web server package for Node.js.
|
|
5
6
|
|
|
6
|
-
by
|
|
7
|
+
by JustApple
|
|
7
8
|
*/
|
|
8
9
|
|
|
9
|
-
//
|
|
10
|
+
// dependencies
|
|
10
11
|
const http = require('http');
|
|
11
12
|
const https = require('https');
|
|
12
|
-
const
|
|
13
|
+
const http2 = require('http2');
|
|
14
|
+
const path = require('path');
|
|
15
|
+
const stream = require('stream');
|
|
13
16
|
const EventEmitter = require('events');
|
|
14
17
|
|
|
15
|
-
//
|
|
16
|
-
const processMap = require('./map.js');
|
|
17
|
-
|
|
18
|
-
//http server
|
|
18
|
+
// server class
|
|
19
19
|
class Server extends EventEmitter {
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
20
|
+
constructor(router, options = {}) {
|
|
21
|
+
super();
|
|
22
|
+
|
|
23
|
+
this.router = router;
|
|
24
|
+
this.options = options;
|
|
25
|
+
|
|
26
|
+
// start a server
|
|
27
|
+
this.server = options.enableHTTP2 ?
|
|
28
|
+
((options.key && options.cert) ?
|
|
29
|
+
http2.createSecureServer(options) :
|
|
30
|
+
http2.createServer(options)) :
|
|
31
|
+
((options.key && options.cert) ?
|
|
32
|
+
https.createServer(options) :
|
|
33
|
+
http.createServer(options));
|
|
34
|
+
|
|
35
|
+
// request listener
|
|
36
|
+
// HTTP/2 also use the same event with the node:http2 Compatibility API
|
|
37
|
+
this.server.on('request', async (req, res) => {
|
|
38
|
+
let url;
|
|
39
|
+
|
|
40
|
+
try {
|
|
41
|
+
url = new URL(req.url, `http${options.key && options.cert ? 's' : ''}://${req.headers.host || req.headers[':authority']}`);
|
|
42
|
+
} catch (e) {
|
|
43
|
+
this.emit('warn', e);
|
|
44
|
+
res.writeHead(400, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
45
|
+
res.end('400 Bad Request', 'utf8');
|
|
46
|
+
return;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// the context object, mainly for handlers
|
|
50
|
+
const ctx = {
|
|
51
|
+
req, res, url,
|
|
52
|
+
server: this,
|
|
53
|
+
path: url.pathname,
|
|
54
|
+
host: url.hostname,
|
|
55
|
+
method: req.method,
|
|
56
|
+
headers: req.headers,
|
|
57
|
+
identity: { address: req.socket.remoteAddress, port: req.socket.remotePort },
|
|
58
|
+
params: Object.fromEntries(url.searchParams.entries()),
|
|
59
|
+
body: req
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
// the environment object, mainly for routers
|
|
63
|
+
const env = {
|
|
64
|
+
path: url.pathname.split('/').slice(1).map((i) => { try { return decodeURIComponent(i); } catch { return i; } }),
|
|
65
|
+
pathPointer: 0,
|
|
66
|
+
host: url.hostname.split('.').filter(Boolean).reverse(),
|
|
67
|
+
hostPointer: 0,
|
|
68
|
+
codeHandlers: this.options.codeHandlers || {},
|
|
69
|
+
i: 0
|
|
70
|
+
};
|
|
71
|
+
|
|
72
|
+
let handler;
|
|
73
|
+
try {
|
|
74
|
+
handler = await Server.route(this.router, env, ctx, this.options);
|
|
75
|
+
if (handler === undefined || handler === null) handler = 404;
|
|
76
|
+
} catch (e) { // error while routing
|
|
77
|
+
this.emit('e', e, env, ctx);
|
|
78
|
+
handler = 500;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
await Server.handle(handler, env, ctx, this.options);
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// route
|
|
86
|
+
static async route(router, env = {}, ctx = {}, options = {}) {
|
|
87
|
+
let r = router;
|
|
88
|
+
if (!env.i) env.i = 0;
|
|
89
|
+
|
|
90
|
+
while (typeof r?.route === 'function') {
|
|
91
|
+
env.i++;
|
|
92
|
+
|
|
93
|
+
if (env.i > (options.maxRoutingSteps || 50)) return 508; // 508 Loop Detected
|
|
94
|
+
|
|
95
|
+
r = await r.route(env, ctx);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return r;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// handle
|
|
102
|
+
static async handle(handler, env = {}, ctx = {}, options = {}) {
|
|
103
|
+
try {
|
|
104
|
+
if (typeof handler?.handle === 'function') { // handler
|
|
105
|
+
await handler.handle(ctx, env);
|
|
106
|
+
} else if (typeof handler === 'function') { // function
|
|
107
|
+
await handler(ctx, env);
|
|
108
|
+
} else if (typeof handler === 'string') { // string
|
|
109
|
+
ctx.res.writeHead(200, {
|
|
110
|
+
'Content-Type': 'text/plain; charset=utf-8',
|
|
111
|
+
'Content-Length': Buffer.byteLength(handler, 'utf8')
|
|
112
|
+
});
|
|
113
|
+
ctx.res.end(handler, 'utf8');
|
|
114
|
+
} else if (handler instanceof Uint8Array) { // buffer
|
|
115
|
+
ctx.res.writeHead(200, {
|
|
116
|
+
'Content-Type': 'application/octet-stream',
|
|
117
|
+
'Content-Length': handler.length
|
|
118
|
+
});
|
|
119
|
+
ctx.res.end(handler);
|
|
120
|
+
} else if (stream.isReadable(handler)) { // stream
|
|
121
|
+
ctx.res.writeHead(200, { 'Content-Type': 'application/octet-stream' });
|
|
122
|
+
await stream.promises.pipeline(handler, ctx.res);
|
|
123
|
+
} else if (typeof handler === 'number') { // status code
|
|
124
|
+
const code = handler;
|
|
125
|
+
handler = env.codeHandlers[code];
|
|
126
|
+
|
|
127
|
+
// handlers without code handlers
|
|
128
|
+
if (typeof handler?.handle === 'function') { // handler
|
|
129
|
+
await handler.handle(ctx, env);
|
|
130
|
+
} else if (typeof handler === 'function') { // function
|
|
131
|
+
await handler(ctx, env);
|
|
132
|
+
} else if (typeof handler === 'string') { // string
|
|
133
|
+
ctx.res.writeHead(code, {
|
|
134
|
+
'Content-Type': 'text/plain; charset=utf-8',
|
|
135
|
+
'Content-Length': Buffer.byteLength(handler, 'utf8')
|
|
136
|
+
});
|
|
137
|
+
ctx.res.end(handler, 'utf8');
|
|
138
|
+
} else if (handler instanceof Uint8Array) { // buffer
|
|
139
|
+
ctx.res.writeHead(code, {
|
|
140
|
+
'Content-Type': 'application/octet-stream',
|
|
141
|
+
'Content-Length': handler.length
|
|
142
|
+
});
|
|
143
|
+
ctx.res.end(handler);
|
|
144
|
+
} else if (stream.isReadable(handler)) { // stream
|
|
145
|
+
ctx.res.writeHead(code, { 'Content-Type': 'application/octet-stream' });
|
|
146
|
+
await stream.promises.pipeline(handler, ctx.res);
|
|
147
|
+
} else { // use default status code response
|
|
148
|
+
try { ctx.res.writeHead(code, { 'Content-Type': 'text/plain; charset=utf-8' }); } catch { }
|
|
149
|
+
try { ctx.res.end(`${code} ${http.STATUS_CODES[code] || 'Unknown'}`, 'utf8'); } catch { }
|
|
150
|
+
}
|
|
151
|
+
} else { // invalid handler
|
|
152
|
+
throw new Error('JNS: Invalid handler returned from router.');
|
|
153
|
+
}
|
|
154
|
+
} catch (e) { // error while handling
|
|
155
|
+
if (typeof e !== 'number') ctx.server.emit('e', e, env, ctx);
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
const code = (typeof e === 'number') ? e : 500;
|
|
159
|
+
handler = env.codeHandlers[code];
|
|
160
|
+
|
|
161
|
+
// handlers without code handlers
|
|
162
|
+
if (typeof handler?.handle === 'function') { // handler
|
|
163
|
+
await handler.handle(ctx, env);
|
|
164
|
+
} else if (typeof handler === 'function') { // function
|
|
165
|
+
await handler(ctx, env);
|
|
166
|
+
} else if (typeof handler === 'string') { // string
|
|
167
|
+
ctx.res.writeHead(code, {
|
|
168
|
+
'Content-Type': 'text/plain; charset=utf-8',
|
|
169
|
+
'Content-Length': Buffer.byteLength(handler, 'utf8')
|
|
170
|
+
});
|
|
171
|
+
ctx.res.end(handler, 'utf8');
|
|
172
|
+
} else if (handler instanceof Uint8Array) { // buffer
|
|
173
|
+
ctx.res.writeHead(code, {
|
|
174
|
+
'Content-Type': 'application/octet-stream',
|
|
175
|
+
'Content-Length': handler.length
|
|
176
|
+
});
|
|
177
|
+
ctx.res.end(handler);
|
|
178
|
+
} else if (stream.isReadable(handler)) { // stream
|
|
179
|
+
ctx.res.writeHead(code, { 'Content-Type': 'application/octet-stream' });
|
|
180
|
+
await stream.promises.pipeline(handler, ctx.res);
|
|
181
|
+
} else { // use default status code response
|
|
182
|
+
ctx.res.writeHead(code, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
183
|
+
ctx.res.end(`${code} ${http.STATUS_CODES[code] || 'Unknown'}`, 'utf8');
|
|
184
|
+
}
|
|
185
|
+
} catch (e) { // error while handling the error while handling :)
|
|
186
|
+
ctx.server.emit('warn', e, env, ctx);
|
|
187
|
+
try { ctx.res.writeHead(500, { 'Content-Type': 'text/plain; charset=utf-8' }); } catch { }
|
|
188
|
+
try { ctx.res.end('500 Internal Server Error', 'utf8'); } catch { }
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
listen(...args) {
|
|
194
|
+
this.server.listen(...args);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
close(...args) {
|
|
198
|
+
this.server.close(...args);
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
// throw an error event
|
|
202
|
+
throw(...args) {
|
|
203
|
+
this.emit('e', ...args);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
// create server
|
|
208
|
+
function createServer(router, options = {}) {
|
|
209
|
+
return new Server(router, options);
|
|
52
210
|
}
|
|
53
211
|
|
|
54
|
-
//export
|
|
55
|
-
module.exports =
|
|
212
|
+
// export
|
|
213
|
+
module.exports = {
|
|
214
|
+
Server,
|
|
215
|
+
createServer
|
|
216
|
+
};
|
package/src/error.js
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
JustServer/error.js
|
|
3
|
-
|
|
4
|
-
Simple web server package for Node.js.
|
|
5
|
-
|
|
6
|
-
by JustNode Dev Team / JustApple
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
//load classes and functions
|
|
10
|
-
const processFinal = require('./final.js');
|
|
11
|
-
|
|
12
|
-
//process HandleObject error
|
|
13
|
-
async function processError(req, res, map, p, e) {
|
|
14
|
-
try {
|
|
15
|
-
//500 error
|
|
16
|
-
return await processFinal(req, res, map['!500'] ?? e.default['!500'] ?? { //default error response
|
|
17
|
-
'+STATUS': 500,
|
|
18
|
-
'TEXT': '500 Internal server error.'
|
|
19
|
-
}, p, e);
|
|
20
|
-
} catch (err) {
|
|
21
|
-
//last error response
|
|
22
|
-
try { res.writeHead(500, { 'Content-Type': 'text/plain' }); } catch { }
|
|
23
|
-
try { res.end('500 Internal server error.'); } catch { }
|
|
24
|
-
|
|
25
|
-
//emit error
|
|
26
|
-
e.emitError(err);
|
|
27
|
-
return;
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
//export
|
|
32
|
-
module.exports = processError;
|
package/src/final.js
DELETED
|
@@ -1,129 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
JustServer/final.js
|
|
3
|
-
|
|
4
|
-
Simple web server package for Node.js.
|
|
5
|
-
|
|
6
|
-
by JustNode Dev Team / JustApple
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
//load node packages
|
|
10
|
-
const path = require('path');
|
|
11
|
-
const fs = require('fs');
|
|
12
|
-
const fsPromises = fs.promises;
|
|
13
|
-
|
|
14
|
-
//load mime types
|
|
15
|
-
const mimeTypes = require('./mime.json');
|
|
16
|
-
|
|
17
|
-
//process FinalObject
|
|
18
|
-
async function processFinal(req, res, map, p, e) {
|
|
19
|
-
//firewall
|
|
20
|
-
if (
|
|
21
|
-
(map['+FIREWALL'] ?? e.default['+FIREWALL']) &&
|
|
22
|
-
!(await (map['+FIREWALL'] ?? e.default['+FIREWALL'])(req, res, map, p, e))
|
|
23
|
-
) return;
|
|
24
|
-
|
|
25
|
-
//custom function
|
|
26
|
-
if (map['FUNCTION']) return map['FUNCTION'](req, res, map, p, e);
|
|
27
|
-
|
|
28
|
-
//text response (include empty text)
|
|
29
|
-
if (map['TEXT'] !== undefined) {
|
|
30
|
-
res.writeHead(map['+STATUS'] ?? 200, {
|
|
31
|
-
'Content-Type': 'text/plain; charset=UTF-8',
|
|
32
|
-
'Content-Length': Buffer.byteLength(map['TEXT']),
|
|
33
|
-
...map['+HEADERS']
|
|
34
|
-
});
|
|
35
|
-
res.end(map['TEXT'], 'utf8');
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
//buffer (binary) response
|
|
40
|
-
if (map['BUFFER']) {
|
|
41
|
-
res.writeHead(map['+STATUS'] ?? 200, {
|
|
42
|
-
'Content-Type': 'application/octet-stream',
|
|
43
|
-
'Content-Length': map['BUFFER'].length,
|
|
44
|
-
...map['+HEADERS']
|
|
45
|
-
});
|
|
46
|
-
res.end(map['BUFFER']);
|
|
47
|
-
return;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
//file response
|
|
51
|
-
if (map['FILE']) {
|
|
52
|
-
let fileSize;
|
|
53
|
-
|
|
54
|
-
//get file size and check file exists
|
|
55
|
-
try {
|
|
56
|
-
fileSize = (await fsPromises.stat(map['FILE'])).size;
|
|
57
|
-
} catch (err) { return '!404'; } //return error
|
|
58
|
-
|
|
59
|
-
//write head
|
|
60
|
-
res.writeHead(map['+STATUS'] ?? 200, {
|
|
61
|
-
'Content-Type': mimeTypes[path.extname(map['FILE'])] ?? 'application/octet-stream',
|
|
62
|
-
'Content-Length': fileSize,
|
|
63
|
-
...map['+HEADERS']
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
//stream response
|
|
67
|
-
const readStream = fs.createReadStream(map['FILE']);
|
|
68
|
-
readStream.pipe(res);
|
|
69
|
-
|
|
70
|
-
//wait for stream
|
|
71
|
-
return await new Promise((resolve, reject) => {
|
|
72
|
-
readStream.on('error', reject);
|
|
73
|
-
readStream.on('end', resolve);
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
//folder
|
|
78
|
-
if (map['FOLDER']) {
|
|
79
|
-
//get file path
|
|
80
|
-
const file = path.resolve(map['FOLDER'], p.map((e) => encodeURIComponent(e)).join('/'));
|
|
81
|
-
|
|
82
|
-
//check file path
|
|
83
|
-
if (path.relative(path.resolve(map['FOLDER']), file).startsWith('..')) return '!403';
|
|
84
|
-
|
|
85
|
-
//check hidden file
|
|
86
|
-
if (
|
|
87
|
-
path.basename(file).startsWith('.') &&
|
|
88
|
-
!(map['__ALLOW_HIDDEN_FILE'] || e.default['__ALLOW_HIDDEN_FILE'])
|
|
89
|
-
) return '!404';
|
|
90
|
-
|
|
91
|
-
let fileSize;
|
|
92
|
-
|
|
93
|
-
//get file size and check file exists
|
|
94
|
-
try {
|
|
95
|
-
const stat = await fsPromises.stat(file);
|
|
96
|
-
if (stat.isDirectory()) return '!404'; //return error for directory
|
|
97
|
-
fileSize = stat.size;
|
|
98
|
-
} catch (err) { return '!404'; } //return error
|
|
99
|
-
|
|
100
|
-
//write head
|
|
101
|
-
res.writeHead(map['+STATUS'] ?? 200, {
|
|
102
|
-
'Content-Type': mimeTypes[path.extname(file)] ?? 'application/octet-stream',
|
|
103
|
-
'Content-Length': fileSize,
|
|
104
|
-
...map['+HEADERS']
|
|
105
|
-
});
|
|
106
|
-
|
|
107
|
-
//stream response
|
|
108
|
-
const readStream = fs.createReadStream(file);
|
|
109
|
-
readStream.pipe(res);
|
|
110
|
-
|
|
111
|
-
//wait for stream
|
|
112
|
-
return await new Promise((resolve, reject) => {
|
|
113
|
-
readStream.on('error', reject);
|
|
114
|
-
readStream.on('end', resolve);
|
|
115
|
-
});
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
//only headers or status code
|
|
119
|
-
if (map['+STATUS'] || map['+HEADERS']) {
|
|
120
|
-
res.writeHead(map['+STATUS'] ?? 200, map['+HEADERS']);
|
|
121
|
-
res.end();
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return '!404';
|
|
126
|
-
}
|
|
127
|
-
|
|
128
|
-
//export
|
|
129
|
-
module.exports = processFinal;
|
package/src/handle.js
DELETED
|
@@ -1,88 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
JustServer/handle.js
|
|
3
|
-
|
|
4
|
-
Simple web server package for Node.js.
|
|
5
|
-
|
|
6
|
-
by JustNode Dev Team / JustApple
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
//load classes and functions
|
|
10
|
-
const processFinal = require('./final.js');
|
|
11
|
-
const processError = require('./error.js');
|
|
12
|
-
|
|
13
|
-
//error handler function
|
|
14
|
-
async function handleStatus(req, res, map, p, e, status) {
|
|
15
|
-
let statusCode;
|
|
16
|
-
let defaultMap;
|
|
17
|
-
|
|
18
|
-
switch (status) {
|
|
19
|
-
case '!404':
|
|
20
|
-
statusCode = 404;
|
|
21
|
-
defaultMap = e.default['!404'] ?? {
|
|
22
|
-
'+STATUS': 404,
|
|
23
|
-
'TEXT': '404 Page not found.'
|
|
24
|
-
};
|
|
25
|
-
break;
|
|
26
|
-
case '!403':
|
|
27
|
-
statusCode = 403;
|
|
28
|
-
defaultMap = e.default['!403'] ?? {
|
|
29
|
-
'+STATUS': 403,
|
|
30
|
-
'TEXT': '403 Forbidden.'
|
|
31
|
-
};
|
|
32
|
-
break;
|
|
33
|
-
default:
|
|
34
|
-
return status; //if status is not a special error, return it directly
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
return await processFinal(req, res, map[status] ?? defaultMap, p, e);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
//process function with error handling
|
|
41
|
-
async function safeProcessFinal(req, res, map, p, e, finalObject) {
|
|
42
|
-
try {
|
|
43
|
-
let status = await processFinal(req, res, finalObject, p, e);
|
|
44
|
-
|
|
45
|
-
//handle special status codes
|
|
46
|
-
status = await handleStatus(req, res, map, p, e, status);
|
|
47
|
-
|
|
48
|
-
//fall into loop error
|
|
49
|
-
if ((typeof status === 'string') && status.startsWith('!')) {
|
|
50
|
-
throw new Error('Process may fall into infinity loop.');
|
|
51
|
-
}
|
|
52
|
-
return status;
|
|
53
|
-
} catch (err) {
|
|
54
|
-
//emit error
|
|
55
|
-
e.emitError(err);
|
|
56
|
-
|
|
57
|
-
//internal server error
|
|
58
|
-
return processError(req, res, map, p, e);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
//process HandleObject
|
|
63
|
-
async function processHandle(req, res, map, p, e) {
|
|
64
|
-
//protocol upgrade
|
|
65
|
-
if (
|
|
66
|
-
req.headers.connection &&
|
|
67
|
-
req.headers.connection.toLowerCase() === 'upgrade' &&
|
|
68
|
-
map['^' + req.headers.upgrade]
|
|
69
|
-
) {
|
|
70
|
-
return await safeProcessFinal(req, res, map, p, e, map['^' + req.headers.upgrade]);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
//method check
|
|
74
|
-
if (map['@' + req.method]) {
|
|
75
|
-
return await safeProcessFinal(req, res, map, p, e, map['@' + req.method]);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
//get final object by function
|
|
79
|
-
if (map['>']) {
|
|
80
|
-
return await safeProcessFinal(req, res, map, p, e, await map['>'](req, res, map, p, e));
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
//process final
|
|
84
|
-
return await safeProcessFinal(req, res, map, p, e, map);
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
//export
|
|
88
|
-
module.exports = processHandle;
|
package/src/map.js
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
JustServer/map.js
|
|
3
|
-
|
|
4
|
-
Simple web server package for Node.js.
|
|
5
|
-
|
|
6
|
-
by JustNode Dev Team / JustApple
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
//load classes and functions
|
|
10
|
-
const processHandle = require('./handle.js');
|
|
11
|
-
const processFinal = require('./final.js');
|
|
12
|
-
const processError = require('./error.js');
|
|
13
|
-
|
|
14
|
-
//process MapObject
|
|
15
|
-
async function processMap(req, res, map, p, e) {
|
|
16
|
-
//overwrite default handle object
|
|
17
|
-
Object.assign(e.default, map['#']);
|
|
18
|
-
|
|
19
|
-
//path ends, process HandleObject
|
|
20
|
-
if (p.length === 0) return await processHandle(req, res, map, p, e);
|
|
21
|
-
|
|
22
|
-
//specific path
|
|
23
|
-
if (map['/' + p[0]]) return await processMap(req, res, map['/' + p.shift()], p, e);
|
|
24
|
-
|
|
25
|
-
//any path
|
|
26
|
-
if (map['*']) {
|
|
27
|
-
p.shift(); //remove first one
|
|
28
|
-
return await processMap(req, res, map['*'], p, e);
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
//any path following
|
|
32
|
-
if (map['**']) return await processHandle(req, res, map['**'], p, e);
|
|
33
|
-
|
|
34
|
-
//page not found
|
|
35
|
-
try {
|
|
36
|
-
return await processFinal(req, res, map['!404'] ?? e.default['!404'] ?? { //default error response
|
|
37
|
-
'+STATUS': 404,
|
|
38
|
-
'TEXT': '404 Page not found.'
|
|
39
|
-
}, p, e);
|
|
40
|
-
} catch (err) {
|
|
41
|
-
//emit error
|
|
42
|
-
e.emitError(err);
|
|
43
|
-
|
|
44
|
-
//internal server error
|
|
45
|
-
return processError(req, res, map, p, e);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
//export
|
|
50
|
-
module.exports = processMap;
|