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 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 destroying the socket connection before the entire payload is processed.
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 destroyed and a `413 Payload Too Large` error is thrown.
131
- - **Unregistered Routes**: When a payload exceeds the limit on an unregistered route, the socket is destroyed and a `404 Not Found` error is thrown.
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. The socket connection is immediately destroyed
140
- 2. An appropriate error response is thrown (413 for registered routes, 404 for unregistered routes)
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
- throw Boom.entityTooLarge(`Payload content length greater than maximum allowed: ${option}`);
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
- throw Boom.notFound();
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, throwError) => {
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 > limit) {
65
- request.raw.req.socket?.destroy();
66
- throwError(limit);
69
+ if (contentLength <= limit) {
70
+ return h.continue;
67
71
  }
68
- return h.continue;
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.1.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.1.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",