hapi-terminator 0.2.0 → 0.3.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
@@ -108,14 +108,56 @@ server.route({
108
108
  await server.start();
109
109
  ```
110
110
 
111
+ ### Boolean Limits for Unregistered Routes
112
+
113
+ You can use boolean values for `unregisteredLimit` to control unregistered route behavior:
114
+
115
+ ```typescript
116
+ import Hapi from '@hapi/hapi';
117
+ import terminatorPlugin, { type TerminatorOptions } from 'hapi-terminator';
118
+
119
+ const server = Hapi.server({ port: 3000, host: '127.0.0.1' });
120
+
121
+ // Reject all unregistered routes immediately
122
+ await server.register({
123
+ plugin: terminatorPlugin,
124
+ options: {
125
+ registeredLimit: 1024 * 1024, // 1MB for registered routes
126
+ unregisteredLimit: true, // Immediately reject all unregistered routes
127
+ },
128
+ });
129
+
130
+ // This route will work normally
131
+ server.route({
132
+ method: ['POST'],
133
+ path: '/api/data',
134
+ handler: () => ({ success: true }),
135
+ });
136
+
137
+ // Any request to unregistered routes (e.g., /unknown) will be rejected immediately
138
+ await server.start();
139
+ ```
140
+
141
+ You can also set `unregisteredLimit` to `false` to bypass payload size checks for unregistered routes:
142
+
143
+ ```typescript
144
+ await server.register({
145
+ plugin: terminatorPlugin,
146
+ options: {
147
+ registeredLimit: 500 * 1024, // 500KB for registered routes
148
+ unregisteredLimit: false, // Bypass payload size checks for unregistered routes
149
+ },
150
+ });
151
+ ```
152
+
111
153
  ## Configuration
112
154
 
113
155
  ### TerminatorOptions
114
156
 
115
- | Option | Type | Description |
116
- | ------------------- | -------- | ------------------------------------------------------------------------------------------------------------- |
117
- | `registeredLimit` | `number` | Maximum payload size in bytes for registered routes. Must be >= 0. Set to `null` or `undefined` to disable. |
118
- | `unregisteredLimit` | `number` | Maximum payload size in bytes for unregistered routes. Must be >= 0. Set to `null` or `undefined` to disable. |
157
+ | Option | Type | Description |
158
+ | ------------------- | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
159
+ | `registeredLimit` | `number` | Maximum payload size in bytes for registered routes. Must be >= 0. Set to `null` or `undefined` to disable. |
160
+ | `unregisteredLimit` | `number \| boolean` | Maximum payload size in bytes for unregistered routes. Must be >= 0. Set to `null` or `undefined` to disable. Set to `true` to reject all requests immediately. Set to `false` to bypass payload size checks. |
119
161
 
120
162
  ### TerminatorRouteOptions
121
163
 
@@ -131,6 +173,9 @@ You can configure per-route limits using the route options:
131
173
  - **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
174
  - **Per-Route Limits**: Route-specific limits take precedence over global limits, allowing you to customize limits for individual routes.
133
175
  - **Disabled**: Set to `null` or `undefined` to disable termination for that category or route.
176
+ - **Boolean Values for Unregistered Routes**:
177
+ - Set `unregisteredLimit` to `true` to immediately reject all unregistered route requests regardless of Content-Length (even 0 bytes).
178
+ - Set `unregisteredLimit` to `false` to bypass payload size checks for unregistered route requests (they will still receive 404 responses).
134
179
 
135
180
  ## How It Works
136
181
 
package/dist/index.d.ts CHANGED
@@ -60,7 +60,7 @@ declare const TerminatorRouteOptionsSchema: z.ZodMiniOptional<z.ZodMiniNullable<
60
60
  }, z.core.$strip>>>;
61
61
  declare const TerminatorOptionsSchema: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniObject<{
62
62
  registeredLimit: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
63
- unregisteredLimit: z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>;
63
+ unregisteredLimit: z.ZodMiniUnion<readonly [z.ZodMiniOptional<z.ZodMiniNullable<z.ZodMiniNumber<number>>>, z.ZodMiniBoolean<boolean>]>;
64
64
  }, z.core.$strip>>>;
65
65
  declare function register(server: Server, rawOptions: TerminatorOptions): Promise<void>;
66
66
  declare const _default: {
package/dist/index.js CHANGED
@@ -8,9 +8,11 @@ const LIMIT_OPTION_NAMES = {
8
8
  const PACKAGE_NAME = 'hapi-terminator';
9
9
  assert(PACKAGE_NAME === pkg.name);
10
10
  export const plugin = { pkg, register };
11
- const LimitOptionShape = z.nullish(z.number().check(z.minimum(0)));
12
- const TerminatorRouteOptionsSchema = z.nullish(z.object({ [PACKAGE_NAME]: z.object({ limit: LimitOptionShape }) }));
13
- const TerminatorOptionsSchema = z.nullish(z.object({ registeredLimit: LimitOptionShape, unregisteredLimit: LimitOptionShape }));
11
+ const TerminatorRouteOptionsSchema = z.nullish(z.object({ [PACKAGE_NAME]: z.object({ limit: z.nullish(z.number().check(z.minimum(0))) }) }));
12
+ const TerminatorOptionsSchema = z.nullish(z.object({
13
+ registeredLimit: z.nullish(z.number().check(z.minimum(0))),
14
+ unregisteredLimit: z.union([z.nullish(z.number().check(z.minimum(0))), z.boolean()]),
15
+ }));
14
16
  async function register(server, rawOptions) {
15
17
  const options = TerminatorOptionsSchema.parse(rawOptions);
16
18
  const routeOptionsCache = new Map();
@@ -66,6 +68,16 @@ function validateRoute(request, h, options) {
66
68
  if (limit == null) {
67
69
  return h.continue;
68
70
  }
71
+ if (limit === false) {
72
+ return h.continue;
73
+ }
74
+ if (limit === true) {
75
+ const result = response(0).takeover();
76
+ request.raw.res.once('finish', () => {
77
+ request.raw.req.socket.end();
78
+ });
79
+ return result;
80
+ }
69
81
  if (contentLength <= limit) {
70
82
  return h.continue;
71
83
  }
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.2.0",
6
+ "version": "0.3.0",
7
7
  "license": "MIT",
8
8
  "author": {
9
9
  "name": "Kamaal Farah"
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.2.0",
6
+ "version": "0.3.0",
7
7
  "license": "MIT",
8
8
  "author": {
9
9
  "name": "Kamaal Farah"