slower 1.1.12 → 1.1.13
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/router.js +17 -25
- package/lib/utils.js +3 -1
- package/package.json +1 -1
- package/readme.md +103 -0
package/lib/router.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
const http = require('http');
|
|
2
2
|
const fs = require('fs');
|
|
3
|
-
const { noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders } = require('./utils');
|
|
3
|
+
const { clone, noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders } = require('./utils');
|
|
4
4
|
|
|
5
5
|
class Route {
|
|
6
6
|
constructor (path, type, callback) {
|
|
@@ -37,7 +37,7 @@ class SlowerRouter {
|
|
|
37
37
|
this.routes = [];
|
|
38
38
|
this.middleware = [noop];
|
|
39
39
|
this.fallback = noop;
|
|
40
|
-
this.allowedMethods =
|
|
40
|
+
this.allowedMethods = clone(SlowerRouter.http_methods);
|
|
41
41
|
this.blockedMethodCallback = noop;
|
|
42
42
|
}
|
|
43
43
|
|
|
@@ -72,7 +72,7 @@ class SlowerRouter {
|
|
|
72
72
|
setRoute = function (path = '/', type = 'GET', callback) {
|
|
73
73
|
let stat = new Route(path, type, callback);
|
|
74
74
|
this.routes.push(stat);
|
|
75
|
-
return
|
|
75
|
+
return this;
|
|
76
76
|
}
|
|
77
77
|
|
|
78
78
|
/**
|
|
@@ -82,13 +82,10 @@ class SlowerRouter {
|
|
|
82
82
|
* @returns {Array} The used middlewares list
|
|
83
83
|
*/
|
|
84
84
|
setMiddleware = function (callback) {
|
|
85
|
-
|
|
85
|
+
this.middleware.push((typeof callback == 'function' ? callback : noop));
|
|
86
|
+
return this;
|
|
86
87
|
}
|
|
87
88
|
|
|
88
|
-
// SERVES FILES FOR SPECIFIC PATHS. WILDCARS ALLOWED. BE CAREFUL - PATH TRAVERSAL MAY BE POSSIBLE
|
|
89
|
-
// Use app.setStatic('/*', __dirname+'/') for serving all local files.
|
|
90
|
-
// or use app.setStatic('/*', __dirname+'/public/') for serving files in a specific folder (public).
|
|
91
|
-
// This is a one-liner for the setRoute function, when the route responds with a simple page or document
|
|
92
89
|
/**
|
|
93
90
|
* Defines a route for a determined request method
|
|
94
91
|
* @category Router
|
|
@@ -97,8 +94,6 @@ class SlowerRouter {
|
|
|
97
94
|
* @param {String} mime The file's mime type
|
|
98
95
|
* @param {Object} replacementData The replacement data map for the dynamic HTML rendering
|
|
99
96
|
* @returns {Object} An Route object already configured
|
|
100
|
-
* @example <caption> Defining a simple GET route:</caption>
|
|
101
|
-
* setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html', 'utf8');
|
|
102
97
|
*/
|
|
103
98
|
/**
|
|
104
99
|
* Dynamic rendering example:
|
|
@@ -117,7 +112,7 @@ class SlowerRouter {
|
|
|
117
112
|
* age: 29
|
|
118
113
|
* }));
|
|
119
114
|
*/
|
|
120
|
-
setDynamic = function (path, file = '', mime = '', replacementData) {
|
|
115
|
+
setDynamic = function (path, file = '', mime = '', replacementData = null) {
|
|
121
116
|
let encoding = (mime === SlowerRouter.mime_table['default'] ? undefined : 'utf-8')
|
|
122
117
|
let stat = new Route(path, 'GET', (req, res) => {
|
|
123
118
|
let data, targetFile, extension, targetMime, targetEncoding;
|
|
@@ -143,7 +138,7 @@ class SlowerRouter {
|
|
|
143
138
|
res.end();
|
|
144
139
|
});
|
|
145
140
|
this.routes.push(stat);
|
|
146
|
-
return
|
|
141
|
+
return this;
|
|
147
142
|
}
|
|
148
143
|
|
|
149
144
|
// SERVES FILES FOR SPECIFIC PATHS. WILDCARS ALLOWED. BE CAREFUL - PATH TRAVERSAL MAY BE POSSIBLE
|
|
@@ -156,10 +151,9 @@ class SlowerRouter {
|
|
|
156
151
|
* @param {String} path The route that will be defined
|
|
157
152
|
* @param {String} file The file path that will be used to respond to the route
|
|
158
153
|
* @param {String} mime The file's mime type
|
|
159
|
-
* @param {String} encoding The file's encoding (defaults to UTF-8)
|
|
160
154
|
* @returns {Object} An Route object already configured
|
|
161
155
|
* @example <caption> Defining a simple GET route:</caption>
|
|
162
|
-
* setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html'
|
|
156
|
+
* setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html');
|
|
163
157
|
*/
|
|
164
158
|
setStatic = function (path, file = '', mime = '') {
|
|
165
159
|
let encoding = (mime === SlowerRouter.mime_table['default'] ? undefined : 'utf-8')
|
|
@@ -184,7 +178,7 @@ class SlowerRouter {
|
|
|
184
178
|
res.end();
|
|
185
179
|
});
|
|
186
180
|
this.routes.push(stat);
|
|
187
|
-
return
|
|
181
|
+
return this;
|
|
188
182
|
}
|
|
189
183
|
|
|
190
184
|
/**
|
|
@@ -192,10 +186,8 @@ class SlowerRouter {
|
|
|
192
186
|
* @category Router
|
|
193
187
|
* @param {String} callback The function to execute for unhandled routes
|
|
194
188
|
* @returns {undefined}
|
|
195
|
-
* @example <caption> Defining a simple GET route:</caption>
|
|
196
|
-
* setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html', 'utf8');
|
|
197
189
|
*/
|
|
198
|
-
setFallback = function (callback) { this.fallback = callback; }
|
|
190
|
+
setFallback = function (callback) { this.fallback = callback; return this; }
|
|
199
191
|
|
|
200
192
|
// SERVES FILES FOR SPECIFIC PATHS. WILDCARS ALLOWED. BE CAREFUL - PATH TRAVERSAL MAY BE POSSIBLE
|
|
201
193
|
// Use app.setStatic('/*', __dirname+'/') for serving all local files.
|
|
@@ -229,7 +221,7 @@ class SlowerRouter {
|
|
|
229
221
|
* age: 29
|
|
230
222
|
* }));
|
|
231
223
|
*/
|
|
232
|
-
setFallbackFile = function (file = '', mime = '', replacementData) {
|
|
224
|
+
setFallbackFile = function (file = '', mime = '', replacementData = null) {
|
|
233
225
|
this.fallback = function fb (req,res) {
|
|
234
226
|
let encoding = (mime === SlowerRouter.mime_table['default'] ? undefined : 'utf-8')
|
|
235
227
|
let data, targetFile, extension, targetMime, targetEncoding;
|
|
@@ -254,6 +246,7 @@ class SlowerRouter {
|
|
|
254
246
|
res.write(data);
|
|
255
247
|
res.end();
|
|
256
248
|
}
|
|
249
|
+
return this;
|
|
257
250
|
}
|
|
258
251
|
|
|
259
252
|
// Sets the methods that the application will respond to. The rest is simply discarded with empty responses.
|
|
@@ -282,7 +275,7 @@ class SlowerRouter {
|
|
|
282
275
|
res.writeHead(405); // sends the meme error 418 'i am a teapot'
|
|
283
276
|
res.end();
|
|
284
277
|
};
|
|
285
|
-
return this
|
|
278
|
+
return this;
|
|
286
279
|
}
|
|
287
280
|
|
|
288
281
|
// Starts the server - listening at <host>:<port>
|
|
@@ -290,10 +283,8 @@ class SlowerRouter {
|
|
|
290
283
|
* @category Router
|
|
291
284
|
* @param {Number} port The port number the server will listen to.
|
|
292
285
|
* @param {String} host The host's network interface address the server will listen into (use a falsy value or '0.0.0.0' for listening on all).
|
|
293
|
-
* @param {Function}
|
|
294
|
-
* @returns {Object} The
|
|
295
|
-
* @example <caption> Allowing only GET and POST:</caption>
|
|
296
|
-
* app.setAllowedMethods(['GET', 'POST']);
|
|
286
|
+
* @param {Function} callback The function to execute after starting the server.
|
|
287
|
+
* @returns {Object<http.Server>} The server instance
|
|
297
288
|
*/
|
|
298
289
|
start = function (port = 8080, host = undefined, callback = () => {}) {
|
|
299
290
|
let routes = this.routes;
|
|
@@ -339,7 +330,8 @@ class SlowerRouter {
|
|
|
339
330
|
});
|
|
340
331
|
callback(server);
|
|
341
332
|
if (!host) host = undefined; // Turn falsy values into undefined, for default behaviour
|
|
342
|
-
return server.listen(port, host);
|
|
333
|
+
// return server.listen(port, host);
|
|
334
|
+
return this;
|
|
343
335
|
}
|
|
344
336
|
}
|
|
345
337
|
|
package/lib/utils.js
CHANGED
|
@@ -141,4 +141,6 @@ const setSocketSecurityHeaders = (req) => {
|
|
|
141
141
|
|
|
142
142
|
const toBool = [() => true, () => false];
|
|
143
143
|
|
|
144
|
-
|
|
144
|
+
const clone = (object) => JSON.parse(JSON.stringify(object));
|
|
145
|
+
|
|
146
|
+
module.exports = { clone, noop, slugify, isSparseEqual, toBool, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders };
|
package/package.json
CHANGED
package/readme.md
CHANGED
|
@@ -3,6 +3,106 @@
|
|
|
3
3
|
Slower is a small web framework, express-like, but simpler and limited.
|
|
4
4
|
It allows for generic route-declaration, fallback pages, and multiple middleware functions.
|
|
5
5
|
|
|
6
|
+
### API Methods:
|
|
7
|
+
|
|
8
|
+
```
|
|
9
|
+
app.enableStrictHeaders(): this
|
|
10
|
+
|
|
11
|
+
> Enables the use of the set of 'Strict Headers'.
|
|
12
|
+
> These headers increase security levels, and are a good practice to apply.
|
|
13
|
+
> However, using these headers in testing scenarios are not a need,
|
|
14
|
+
and may have buggy or negative effects. So, apply those to simulate scenarios only.
|
|
15
|
+
> Headers configured:
|
|
16
|
+
> Content-Security-Policy
|
|
17
|
+
> Cross-Origin-Opener-Policy
|
|
18
|
+
> Cross-Origin-Resource-Policy
|
|
19
|
+
> Origin-Agent-Cluster
|
|
20
|
+
> Referrer-Policy
|
|
21
|
+
> X-DNS-Prefetch-Control (disabled)
|
|
22
|
+
> X-Download-Options
|
|
23
|
+
> X-Frame-Options
|
|
24
|
+
> X-XSS-Protection (disabled)
|
|
25
|
+
> X-Powered-By (removed)
|
|
26
|
+
> Returns the own object instance, so that methods can be chained.
|
|
27
|
+
```
|
|
28
|
+
```
|
|
29
|
+
app.disableStrictHeaders(): this
|
|
30
|
+
|
|
31
|
+
> Disables the use of the set of 'Strict Headers'.
|
|
32
|
+
> See 'enableStrictHeaders()' for more information.
|
|
33
|
+
> Returns the own object instance, so that methods can be chained.
|
|
34
|
+
```
|
|
35
|
+
```
|
|
36
|
+
app.setRoute(string: path = '/', string: type = 'GET', function: callback): this
|
|
37
|
+
|
|
38
|
+
> Creates a new route for path defined in 'path', responding to the HTTP verb defined in 'type' argument.
|
|
39
|
+
> The callback is executed when the route is accessed.
|
|
40
|
+
> Returns the own object instance, so that methods can be chained.
|
|
41
|
+
```
|
|
42
|
+
```
|
|
43
|
+
app.setMiddleware(function: callback): this
|
|
44
|
+
|
|
45
|
+
> Sets a new middleware function: callback function will be accessed for every server access.
|
|
46
|
+
> Many middlewares can be defined, and will be applied in the order they are defined.
|
|
47
|
+
> Returns the own object instance, so that methods can be chained.
|
|
48
|
+
```
|
|
49
|
+
```
|
|
50
|
+
app.setDynamic(string: path, string: file = '', string: mime = '', object: replacementData = null): this
|
|
51
|
+
|
|
52
|
+
> Creates a new GET route for path defined in 'path'.
|
|
53
|
+
> This is a custom file-response route, configured for template rendering just before response.
|
|
54
|
+
> Providing an object as 'replacementData' in this format { valueToBeReplaced: valueToReplace },
|
|
55
|
+
allows for template rendering. The value to replace in the file, uses this notation: '<{content}>'.
|
|
56
|
+
> Example:
|
|
57
|
+
Responding a route for '/custom' with file 'custom.html':
|
|
58
|
+
app.setDynamic('/custom', './templates/custom.html', 'text/html', { smile: ':)' })
|
|
59
|
+
In file './templates/custom.html':
|
|
60
|
+
"<h2> This is a custom thing: <{smile}> </h2>"
|
|
61
|
+
Rendered in browser:
|
|
62
|
+
<h2> This is a custom thing: :) </h2>
|
|
63
|
+
> Returns the own object instance, so that methods can be chained.
|
|
64
|
+
```
|
|
65
|
+
```
|
|
66
|
+
app.setStatic(string: path, string: file = '', string: mime = ''): this
|
|
67
|
+
|
|
68
|
+
> Creates a new GET route for path defined in 'path', responding with the specified file and MIME type.
|
|
69
|
+
> Example: A route for '/login' page, responding with 'login.html' file
|
|
70
|
+
setStatic('/login', __dirname+'/public/static/views/login.html', 'text/html');
|
|
71
|
+
> Returns the own object instance, so that methods can be chained.
|
|
72
|
+
```
|
|
73
|
+
```
|
|
74
|
+
app.setFallback(function: callback): this
|
|
75
|
+
|
|
76
|
+
> Creates a function for fallback state. When no other routes intercept the route, this will be used.
|
|
77
|
+
> Special use for 'page not found' fallback pages or highly customized routes and situations.
|
|
78
|
+
> Returns the own object instance, so that methods can be chained.
|
|
79
|
+
```
|
|
80
|
+
```
|
|
81
|
+
app.setFallbackFile (string: file = '', string: mime = '', object: replacementData = null): this
|
|
82
|
+
|
|
83
|
+
> Creates a function for fallback state. When no other routes intercept the route, this will be used.
|
|
84
|
+
> Equivalent to setFallback, but responds with a file. Allows for template rendering.
|
|
85
|
+
> See 'setDynamic' for more information about template rendering.
|
|
86
|
+
> Special use for 'page not found' fallback pages, ex: './e404.html'.
|
|
87
|
+
> Returns the own object instance, so that methods can be chained.
|
|
88
|
+
```
|
|
89
|
+
```
|
|
90
|
+
app.setAllowedMethods(array: methods = []): this
|
|
91
|
+
|
|
92
|
+
> Sets a list of methods to respond to.
|
|
93
|
+
> By using this, it is possible to restrict the application to avoid
|
|
94
|
+
responding to dangerous HTTP verbs, such as 'DELETE'.
|
|
95
|
+
> By default, all methods are allowed (see Slower.constructor.http_methods)
|
|
96
|
+
> Calling this function without parameters is an easy way to block responses to all requests (lock server).
|
|
97
|
+
> Returns the own object instance, so that methods can be chained.
|
|
98
|
+
```
|
|
99
|
+
```
|
|
100
|
+
app.start(number|string: port = 8080, string: host = undefined, function: callback = ()=>{}): this
|
|
101
|
+
|
|
102
|
+
> Starts the server, at a specific host and port, then calling the callback function.
|
|
103
|
+
> Not defining a specific port or host will start the server at '0.0.0.0:8080'.
|
|
104
|
+
> Returns the own object instance, so that methods can be chained.
|
|
105
|
+
```
|
|
6
106
|
|
|
7
107
|
Example usage:
|
|
8
108
|
```
|
|
@@ -46,6 +146,7 @@ app.start(port, null, () => {
|
|
|
46
146
|
console.log(`Running on localhost:${port}`);
|
|
47
147
|
console.log(app);
|
|
48
148
|
});
|
|
149
|
+
|
|
49
150
|
```
|
|
50
151
|
### API modifications on 'net.Socket' instances:
|
|
51
152
|
- The API modifies every ```net.Socket``` instance BEFORE it is passed
|
|
@@ -71,6 +172,7 @@ So, considering the common callback of ```(req, res)```, the session container w
|
|
|
71
172
|
methods do exacly that. The strict headers are disabled by default, as some resources are too strict,
|
|
72
173
|
but it is also possible to enable them all, and then set a middleware to override any header.
|
|
73
174
|
- Headers set by 'enableStrictHeaders':
|
|
175
|
+
```
|
|
74
176
|
Content-Security-Policy: default-src=none; script-src=self; connect-src=self; img-src=self;
|
|
75
177
|
style-src=self; frame-ancestors=none; form-action=self;
|
|
76
178
|
Cross-Origin-Opener-Policy: same-origin
|
|
@@ -84,3 +186,4 @@ So, considering the common callback of ```(req, res)```, the session container w
|
|
|
84
186
|
X-Frame-Options: DENY
|
|
85
187
|
X-Powered-By: (This header is removed if a response includes it)
|
|
86
188
|
X-XSS-Protection: 0
|
|
189
|
+
```
|