hapi-terminator 0.1.0 → 0.2.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 +5 -5
- package/dist/index.d.ts +0 -2
- package/dist/index.js +17 -9
- package/dist/package.json +1 -2
- package/package.json +1 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# hapi-terminator
|
|
2
2
|
|
|
3
|
-
A Hapi plugin that terminates requests with payloads that exceed a specified size limit. This plugin helps protect your server from excessively large payloads by
|
|
3
|
+
A Hapi plugin that terminates requests with payloads that exceed a specified size limit. This plugin helps protect your server from excessively large payloads by gracefully ending the socket connection before the entire payload is processed.
|
|
4
4
|
|
|
5
5
|
## Features
|
|
6
6
|
|
|
@@ -127,8 +127,8 @@ You can configure per-route limits using the route options:
|
|
|
127
127
|
|
|
128
128
|
### Behavior
|
|
129
129
|
|
|
130
|
-
- **Registered Routes**: When a payload exceeds the limit on a registered route, the socket is
|
|
131
|
-
- **Unregistered Routes**: When a payload exceeds the limit on an unregistered route, the socket is
|
|
130
|
+
- **Registered Routes**: When a payload exceeds the limit on a registered route, the socket is gracefully ended and a `413 Payload Too Large` error is returned.
|
|
131
|
+
- **Unregistered Routes**: When a payload exceeds the limit on an unregistered route, the socket is gracefully ended and a `404 Not Found` error is returned.
|
|
132
132
|
- **Per-Route Limits**: Route-specific limits take precedence over global limits, allowing you to customize limits for individual routes.
|
|
133
133
|
- **Disabled**: Set to `null` or `undefined` to disable termination for that category or route.
|
|
134
134
|
|
|
@@ -136,8 +136,8 @@ You can configure per-route limits using the route options:
|
|
|
136
136
|
|
|
137
137
|
The plugin hooks into Hapi's `onRequest` extension point and checks the `Content-Length` header of incoming requests. If the content length exceeds the configured threshold:
|
|
138
138
|
|
|
139
|
-
1.
|
|
140
|
-
2.
|
|
139
|
+
1. An appropriate error response is returned (413 for registered routes, 404 for unregistered routes)
|
|
140
|
+
2. The socket connection is gracefully ended after the response is sent
|
|
141
141
|
3. No further processing occurs, saving server resources
|
|
142
142
|
|
|
143
143
|
## License
|
package/dist/index.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ export declare const plugin: {
|
|
|
28
28
|
"typescript-eslint": string;
|
|
29
29
|
};
|
|
30
30
|
dependencies: {
|
|
31
|
-
"@hapi/boom": string;
|
|
32
31
|
zod: string;
|
|
33
32
|
};
|
|
34
33
|
prettier: string;
|
|
@@ -91,7 +90,6 @@ declare const _default: {
|
|
|
91
90
|
"typescript-eslint": string;
|
|
92
91
|
};
|
|
93
92
|
dependencies: {
|
|
94
|
-
"@hapi/boom": string;
|
|
95
93
|
zod: string;
|
|
96
94
|
};
|
|
97
95
|
prettier: string;
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import assert from 'node:assert';
|
|
2
|
-
import Boom from '@hapi/boom';
|
|
3
2
|
import { z } from 'zod/mini';
|
|
4
3
|
import pkg from './package.json';
|
|
5
4
|
const LIMIT_OPTION_NAMES = {
|
|
@@ -31,17 +30,23 @@ function validateHookHandler(pluginOptions, routeOptionsCache) {
|
|
|
31
30
|
const { route, options } = getRouteAndOptions(request, routeOptionsCache) ?? {};
|
|
32
31
|
if (route != null) {
|
|
33
32
|
return handler(contentLength, LIMIT_OPTION_NAMES.REGISTERED, options, option => {
|
|
34
|
-
|
|
33
|
+
return h
|
|
34
|
+
.response({
|
|
35
|
+
error: 'Request Entity Too Large',
|
|
36
|
+
message: `Payload content length greater than maximum allowed: ${option}`,
|
|
37
|
+
statusCode: 413,
|
|
38
|
+
})
|
|
39
|
+
.code(413);
|
|
35
40
|
});
|
|
36
41
|
}
|
|
37
42
|
assert(options == null, "Unregistered routes can't have route options");
|
|
38
43
|
return handler(contentLength, LIMIT_OPTION_NAMES.UNREGISTERED, null, () => {
|
|
39
|
-
|
|
44
|
+
return h.response({ error: 'Not Found', message: 'Not Found', statusCode: 404 }).code(404);
|
|
40
45
|
});
|
|
41
46
|
};
|
|
42
47
|
}
|
|
43
48
|
function getRouteAndOptions(request, routeOptionsCache) {
|
|
44
|
-
const matchedRoute = request.server.match(request.method, request.path);
|
|
49
|
+
const matchedRoute = request.server.match(request.method, request.path, request.info.host);
|
|
45
50
|
if (matchedRoute == null) {
|
|
46
51
|
return null;
|
|
47
52
|
}
|
|
@@ -55,17 +60,20 @@ function getRouteAndOptions(request, routeOptionsCache) {
|
|
|
55
60
|
return { options, route: matchedRoute };
|
|
56
61
|
}
|
|
57
62
|
function validateRoute(request, h, options) {
|
|
58
|
-
return (contentLength, optionName, routeOptions,
|
|
63
|
+
return (contentLength, optionName, routeOptions, response) => {
|
|
59
64
|
const option = options?.[optionName];
|
|
60
65
|
const limit = routeOptions?.[PACKAGE_NAME]?.limit ?? option;
|
|
61
66
|
if (limit == null) {
|
|
62
67
|
return h.continue;
|
|
63
68
|
}
|
|
64
|
-
if (contentLength
|
|
65
|
-
|
|
66
|
-
throwError(limit);
|
|
69
|
+
if (contentLength <= limit) {
|
|
70
|
+
return h.continue;
|
|
67
71
|
}
|
|
68
|
-
|
|
72
|
+
const result = response(limit).takeover();
|
|
73
|
+
request.raw.res.once('finish', () => {
|
|
74
|
+
request.raw.req.socket.end();
|
|
75
|
+
});
|
|
76
|
+
return result;
|
|
69
77
|
};
|
|
70
78
|
}
|
|
71
79
|
function getRoutePluginSettings(matchedRoute) {
|
package/dist/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"typings": "dist/index.d.ts",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.2.0",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Kamaal Farah"
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"typescript-eslint": "^8.52.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@hapi/boom": "^10.0.1",
|
|
27
26
|
"zod": "^4.3.5"
|
|
28
27
|
},
|
|
29
28
|
"prettier": "@kamaalio/prettier-config",
|
package/package.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"main": "dist/index.js",
|
|
4
4
|
"typings": "dist/index.d.ts",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"version": "0.
|
|
6
|
+
"version": "0.2.0",
|
|
7
7
|
"license": "MIT",
|
|
8
8
|
"author": {
|
|
9
9
|
"name": "Kamaal Farah"
|
|
@@ -23,7 +23,6 @@
|
|
|
23
23
|
"typescript-eslint": "^8.52.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@hapi/boom": "^10.0.1",
|
|
27
26
|
"zod": "^4.3.5"
|
|
28
27
|
},
|
|
29
28
|
"prettier": "@kamaalio/prettier-config",
|