corecdtl 0.1.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/LICENSE.md +21 -0
- package/README.md +202 -0
- package/build/Release/hypernode.node +0 -0
- package/dist/http/chunker/ChunkParser.d.ts +8 -0
- package/dist/http/chunker/ChunkParser.js +2 -0
- package/dist/http/chunker/ChunkProgression.d.ts +25 -0
- package/dist/http/chunker/ChunkProgression.js +55 -0
- package/dist/http/chunker/FixedChunkedParser.d.ts +14 -0
- package/dist/http/chunker/FixedChunkedParser.js +49 -0
- package/dist/http/chunker/StreamingChunkedParser.d.ts +19 -0
- package/dist/http/chunker/StreamingChunkedParser.js +94 -0
- package/dist/http/chunker/UntilEndChunkerParser.d.ts +37 -0
- package/dist/http/chunker/UntilEndChunkerParser.js +64 -0
- package/dist/http/content/encoding.d.ts +3 -0
- package/dist/http/content/encoding.js +38 -0
- package/dist/http/content/parser.d.ts +1 -0
- package/dist/http/content/parser.js +64 -0
- package/dist/http/context/ApiContext.d.ts +14 -0
- package/dist/http/context/ApiContext.js +151 -0
- package/dist/http/context/HttpContext.d.ts +42 -0
- package/dist/http/context/HttpContext.js +231 -0
- package/dist/http/context/WebContext.d.ts +31 -0
- package/dist/http/context/WebContext.js +320 -0
- package/dist/http/factory/accumulator.d.ts +13 -0
- package/dist/http/factory/accumulator.js +221 -0
- package/dist/http/factory/factory.d.ts +5 -0
- package/dist/http/factory/factory.js +97 -0
- package/dist/http/factory/pipeline.d.ts +3 -0
- package/dist/http/factory/pipeline.js +102 -0
- package/dist/http/response/HttpResponseBase.d.ts +10 -0
- package/dist/http/response/HttpResponseBase.js +2 -0
- package/dist/http/response/PipeResponseBase.d.ts +31 -0
- package/dist/http/response/PipeResponseBase.js +115 -0
- package/dist/http.d.ts +567 -0
- package/dist/http.js +59 -0
- package/dist/hypernode.d.ts +31 -0
- package/dist/hypernode.js +8 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +39 -0
- package/package.json +63 -0
package/dist/http.d.ts
ADDED
|
@@ -0,0 +1,567 @@
|
|
|
1
|
+
import net from "net";
|
|
2
|
+
import { PipeResponseBase } from "./http/response/PipeResponseBase";
|
|
3
|
+
import { ChunkParser } from "./http/chunker/ChunkParser";
|
|
4
|
+
export declare namespace Http {
|
|
5
|
+
/**
|
|
6
|
+
* @type {MiddlewareHandleFn<P, T, R>}
|
|
7
|
+
* @description Defines the signature for a Middleware handler function.
|
|
8
|
+
* Middleware functions intercept requests before they reach the final endpoint.
|
|
9
|
+
*
|
|
10
|
+
* @template P - The type of the request body (payload) expected by this handler (e.g., when a request body schema is known). Defaults to `any` if not specified.
|
|
11
|
+
* @template T - The specific Request object type used by the handler. Defaults to `Request<P>`.
|
|
12
|
+
* @template R - The specific Response object type used by the handler. Defaults to `PipeResponseBase`.
|
|
13
|
+
*
|
|
14
|
+
* @param {T} req - The request object (defaults to Request<P>).
|
|
15
|
+
* @param {R} res - The response object.
|
|
16
|
+
* @returns {void | Promise<void>} The function can be synchronous or asynchronous.
|
|
17
|
+
*/
|
|
18
|
+
export type MiddlewareHandleFn<P = any, T = Request<P>, R = PipeResponseBase> = (req: T, res: R) => void | Promise<void>;
|
|
19
|
+
/**
|
|
20
|
+
* @type {EndpointHandleFn<T, R>}
|
|
21
|
+
* @description Defines the signature for an Endpoint handler function.
|
|
22
|
+
* This function executes the final business logic for a matched route.
|
|
23
|
+
*
|
|
24
|
+
* @template T - The type of the request body (payload) expected by this endpoint. Defaults to `any` if not specified.
|
|
25
|
+
* @template R - The specific Response object type used by the handler. Defaults to `PipeResponseBase`.
|
|
26
|
+
*
|
|
27
|
+
* @param {Request<T>} req - The request object, explicitly typed with the expected body type T.
|
|
28
|
+
* @param {R} res - The response object.
|
|
29
|
+
* @returns {void | Promise<void>} The function can be synchronous or asynchronous.
|
|
30
|
+
*/
|
|
31
|
+
export type EndpointHandleFn<T = any, R = PipeResponseBase> = (req: Request<T>, res: R) => void | Promise<void>;
|
|
32
|
+
export type HandlerPipeFn = (socket: net.Socket, chunk: Buffer, p: Http.ChunkProgression) => void;
|
|
33
|
+
export type HandlerParserFn = (socket: net.Socket, p: Http.ChunkProgression) => void;
|
|
34
|
+
/**
|
|
35
|
+
* @interface Request
|
|
36
|
+
* @description Represents the processed incoming HTTP request object passed to the route handlers (endpoints/middlewares).
|
|
37
|
+
* This object contains all essential parsed request information, ready for developer consumption.
|
|
38
|
+
* The generic type <T> is typically used for the request body data type (e.g., JSON payload).
|
|
39
|
+
* @template T - The expected type of the request body (e.g., object, string, Buffer).
|
|
40
|
+
*/
|
|
41
|
+
export interface Request<T> {
|
|
42
|
+
[key: string]: any;
|
|
43
|
+
/**
|
|
44
|
+
* @property {string} url
|
|
45
|
+
* @description The full request URL path, including the query string (e.g., "/users/123?active=true").
|
|
46
|
+
*/
|
|
47
|
+
url: string;
|
|
48
|
+
/**
|
|
49
|
+
* @property {Record<string, string>} headers
|
|
50
|
+
* @description A key-value map of the parsed HTTP request headers.
|
|
51
|
+
* Keys are typically normalized (e.g., lowercased).
|
|
52
|
+
*/
|
|
53
|
+
headers: Record<string, string>;
|
|
54
|
+
/**
|
|
55
|
+
* @property {string[]} params
|
|
56
|
+
* @description An array containing the values of the dynamic URL parameters defined in the route path.
|
|
57
|
+
* E.g., for route "/users/:id", this array would contain the value of "id".
|
|
58
|
+
*/
|
|
59
|
+
params: string[];
|
|
60
|
+
/**
|
|
61
|
+
* @property {Record<string, string>} query
|
|
62
|
+
* @description A key-value map of the parsed URL query string parameters.
|
|
63
|
+
* E.g., for "?search=term&page=2", this would be { search: "term", page: "2" }.
|
|
64
|
+
*/
|
|
65
|
+
query: Record<string, string>;
|
|
66
|
+
/**
|
|
67
|
+
* @property {T} body
|
|
68
|
+
* @description The request payload (body). The type <T> is determined by the expected content
|
|
69
|
+
* type and how the middleware/framework chooses to process it (e.g., JSON object, raw string, or Buffer).
|
|
70
|
+
*/
|
|
71
|
+
body: T;
|
|
72
|
+
}
|
|
73
|
+
export enum HttpMethod {
|
|
74
|
+
HEAD = 0,
|
|
75
|
+
GET = 1,
|
|
76
|
+
POST = 2,
|
|
77
|
+
PUT = 3,
|
|
78
|
+
DELETE = 4,
|
|
79
|
+
PATCH = 5,
|
|
80
|
+
OPTIONS = 6
|
|
81
|
+
}
|
|
82
|
+
export enum RetFlagBits {
|
|
83
|
+
FLAG_OK = 0,
|
|
84
|
+
FLAG_BAD_REQUEST = 1,
|
|
85
|
+
FLAG_METHOD_NOT_ALLOWED = 2,
|
|
86
|
+
FLAG_NOT_FOUND = 4,
|
|
87
|
+
FLAG_CORS_PREFLIGHT = 8,
|
|
88
|
+
FLAG_HTTP_VERSION_UNSUPPORTED = 16,
|
|
89
|
+
FLAG_CONTENT_LENGTH_TOO_LARGE = 32,
|
|
90
|
+
FLAG_MISSING_HOST = 64,
|
|
91
|
+
FLAG_HAS_BODY = 128,
|
|
92
|
+
FLAG_INVALID_ARGUMENT = 256,
|
|
93
|
+
FLAG_INVALID_HEADER = 512,
|
|
94
|
+
FLAG_INVALID_HEADER_VALUE = 768,
|
|
95
|
+
FLAG_INVALID_CONTENT_LENGTH = 1024,
|
|
96
|
+
FLAG_CONTENT_LENGTH_EXCEEDED = 2048,
|
|
97
|
+
FLAG_UNTERMINATED_HEADERS = 4096,
|
|
98
|
+
FLAG_MAX_HEADER_SIZE = 8192,
|
|
99
|
+
FLAG_MAX_HEADER_NAME_SIZE = 8448,
|
|
100
|
+
FLAG_MAX_HEADER_VALUE_SIZE = 8704,
|
|
101
|
+
FLAG_DUPLICATE_SINGLE_HEADER = 12288,
|
|
102
|
+
FLAG_REQUEST_QUERY_EXCEEDED = 16384,
|
|
103
|
+
FLAG_REQUEST_URL_EXCEEDED = 20480,
|
|
104
|
+
FLAG_SMUGGING_TE_CL = 24576
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* @interface Server
|
|
108
|
+
* @description Defines the public methods and properties of the Http server instance.
|
|
109
|
+
* It is used to configure and manage the server settings and lifecycle.
|
|
110
|
+
*/
|
|
111
|
+
export interface Server {
|
|
112
|
+
/**
|
|
113
|
+
* @method enableCors
|
|
114
|
+
* @description Enables and configures Cross-Origin Resource Sharing (CORS) for the server.
|
|
115
|
+
* @param {CorsConfig} opts - CORS configuration options.
|
|
116
|
+
* @returns {this} The server instance for chaining.
|
|
117
|
+
*/
|
|
118
|
+
enableCors(opts: CorsConfig): this;
|
|
119
|
+
/**
|
|
120
|
+
* @method setTimeout
|
|
121
|
+
* @description Sets the connection timeout value.
|
|
122
|
+
* @param {number} timeout - Timeout duration in milliseconds. Must be greater than 0.
|
|
123
|
+
*/
|
|
124
|
+
setTimeout(timeout: number): void;
|
|
125
|
+
/**
|
|
126
|
+
* @method setRequestQuerySize
|
|
127
|
+
* @description Sets the maximum allowed size for the request query string.
|
|
128
|
+
* @param {number} requestQuerySize - Maximum query string size in bytes. Must be greater than 0.
|
|
129
|
+
*/
|
|
130
|
+
setRequestQuerySize(requestQuerySize: number): void;
|
|
131
|
+
/**
|
|
132
|
+
* @method setMaxHeaderSize
|
|
133
|
+
* @description Sets the maximum allowed size for request headers.
|
|
134
|
+
* @param {number} maxHeaderSize - Maximum header size in bytes. Must be greater than 0.
|
|
135
|
+
*/
|
|
136
|
+
setMaxHeaderSize(maxHeaderSize: number): void;
|
|
137
|
+
/**
|
|
138
|
+
* @method setMaxContentSize
|
|
139
|
+
* @description Sets the maximum allowed size for the request body (content/payload).
|
|
140
|
+
* @param {number} maxContentSize - Maximum content size in bytes. Must be greater than 0.
|
|
141
|
+
*/
|
|
142
|
+
setMaxContentSize(maxContentSize: number): void;
|
|
143
|
+
/**
|
|
144
|
+
* @method getTimeout
|
|
145
|
+
* @description Gets the current connection timeout value.
|
|
146
|
+
* @returns {number} The timeout duration in milliseconds.
|
|
147
|
+
*/
|
|
148
|
+
getTimeout(): number;
|
|
149
|
+
/**
|
|
150
|
+
* @method getRequestQuerySize
|
|
151
|
+
* @description Gets the current maximum request query string size.
|
|
152
|
+
* @returns {number} The maximum query string size in bytes.
|
|
153
|
+
*/
|
|
154
|
+
getRequestQuerySize(): number;
|
|
155
|
+
/**
|
|
156
|
+
* @method getMaxHeaderSize
|
|
157
|
+
* @description Gets the current maximum request header size.
|
|
158
|
+
* @returns {number} The maximum header size in bytes.
|
|
159
|
+
*/
|
|
160
|
+
getMaxHeaderSize(): number;
|
|
161
|
+
/**
|
|
162
|
+
* @method getMaxContentSize
|
|
163
|
+
* @description Gets the current maximum request content size.
|
|
164
|
+
* @returns {number} The maximum content size in bytes.
|
|
165
|
+
*/
|
|
166
|
+
getMaxContentSize(): number;
|
|
167
|
+
/**
|
|
168
|
+
* @property {boolean} listening
|
|
169
|
+
* @description A boolean indicating whether or not the server is listening for connections.
|
|
170
|
+
*/
|
|
171
|
+
listening: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* @method listen
|
|
174
|
+
* @description Starts the server listening for connections.
|
|
175
|
+
* @param {number} [port] - The port to listen on.
|
|
176
|
+
* @param {string} [hostname] - The host name or IP address to listen on.
|
|
177
|
+
* @param {() => void} [listeningListener] - Callback function once the server starts listening.
|
|
178
|
+
* @param {number} [backlog] - The maximum length of the queue of pending connections.
|
|
179
|
+
* @returns {this} The server instance for chaining.
|
|
180
|
+
*/
|
|
181
|
+
listen(port?: number, hostname?: string, listeningListener?: () => void, backlog?: number): this;
|
|
182
|
+
/**
|
|
183
|
+
* @method address
|
|
184
|
+
* @description Returns the bound address, address family name, and port of the server.
|
|
185
|
+
* @returns {net.AddressInfo | string | null} The address info.
|
|
186
|
+
*/
|
|
187
|
+
address(): net.AddressInfo | string | null;
|
|
188
|
+
/**
|
|
189
|
+
* @method setMaxRequests
|
|
190
|
+
* @description Sets the maximum number of concurrent requests the server can handle by resizing internal pools.
|
|
191
|
+
* @param {number} n - The maximum number of concurrent requests. Must be 1 or greater.
|
|
192
|
+
* @returns {boolean} Returns `true` if the pools were successfully resized, `false` otherwise.
|
|
193
|
+
*/
|
|
194
|
+
setMaxRequests: (n: number) => boolean;
|
|
195
|
+
/**
|
|
196
|
+
* @method getMaxListeners
|
|
197
|
+
* @description Gets the current maximum listener value.
|
|
198
|
+
* @returns {number} The maximum number of listeners.
|
|
199
|
+
*/
|
|
200
|
+
getMaxListeners(): number;
|
|
201
|
+
/**
|
|
202
|
+
* @method setMaxListeners
|
|
203
|
+
* @description Sets the max number of listeners.
|
|
204
|
+
* @param {number} n - The maximum number of listeners.
|
|
205
|
+
* @returns {this} The server instance for chaining.
|
|
206
|
+
*/
|
|
207
|
+
setMaxListeners(n: number): this;
|
|
208
|
+
/**
|
|
209
|
+
* @method on
|
|
210
|
+
* @description Registers an event listener for the 'close' event.
|
|
211
|
+
*/
|
|
212
|
+
on(event: 'close', listener: () => void): this;
|
|
213
|
+
/**
|
|
214
|
+
* @method on
|
|
215
|
+
* @description Registers an event listener for the 'connection' event.
|
|
216
|
+
*/
|
|
217
|
+
on(event: 'connection', listener: (socket: net.Socket) => void): this;
|
|
218
|
+
/**
|
|
219
|
+
* @method on
|
|
220
|
+
* @description Registers an event listener for the 'error' event.
|
|
221
|
+
*/
|
|
222
|
+
on(event: 'error', listener: (err: Error) => void): this;
|
|
223
|
+
/**
|
|
224
|
+
* @method on
|
|
225
|
+
* @description Registers an event listener for the 'listening' event.
|
|
226
|
+
*/
|
|
227
|
+
on(event: 'listening', listener: () => void): this;
|
|
228
|
+
/**
|
|
229
|
+
* @method on
|
|
230
|
+
* @description Registers a listener for any specified event.
|
|
231
|
+
* @param {string} event - The name of the event.
|
|
232
|
+
* @param {Function} listener - The callback function.
|
|
233
|
+
*/
|
|
234
|
+
on(event: string, listener: (...args: any[]) => void): this;
|
|
235
|
+
/**
|
|
236
|
+
* @method off
|
|
237
|
+
* @description Removes a registered listener for the specified event.
|
|
238
|
+
* @param {string} event - The name of the event.
|
|
239
|
+
* @param {Function} listener - The callback function to remove.
|
|
240
|
+
*/
|
|
241
|
+
off(event: string, listener: (...args: any[]) => void): this;
|
|
242
|
+
/**
|
|
243
|
+
* @method close
|
|
244
|
+
* @description Stops the server from accepting new connections and keeps existing connections.
|
|
245
|
+
* @param {(err?: Error) => void} [callback] - Called when the server has closed.
|
|
246
|
+
* @returns {this} The server instance for chaining.
|
|
247
|
+
*/
|
|
248
|
+
close(callback?: (err?: Error) => void): this;
|
|
249
|
+
}
|
|
250
|
+
/**
|
|
251
|
+
* @description Represents a map of pre-defined HTTP response buffers for common errors and status codes.
|
|
252
|
+
*/
|
|
253
|
+
export type HttpStaticResponseMap = {
|
|
254
|
+
/** HTTP Version Not Supported: The server does not support the HTTP protocol version used in the request. */
|
|
255
|
+
RESP_505: Buffer;
|
|
256
|
+
/** Method Not Allowed: The request method is known by the server but has been disabled and cannot be used. */
|
|
257
|
+
RESP_405: Buffer;
|
|
258
|
+
/** Bad Request: The server cannot or will not process the request due to something that is perceived to be a client error. */
|
|
259
|
+
RESP_400: Buffer;
|
|
260
|
+
/** Not Found: The server cannot find the requested resource. */
|
|
261
|
+
RESP_404: Buffer;
|
|
262
|
+
/** Payload Too Large: The request entity is larger than limits defined by server. */
|
|
263
|
+
RESP_413: Buffer;
|
|
264
|
+
/** Request-URI Too Large: The URI provided was too long for the server to process. */
|
|
265
|
+
RESP_414: Buffer;
|
|
266
|
+
/** No Content: The server successfully processed the request, and is not returning any content. */
|
|
267
|
+
RESP_204: Buffer;
|
|
268
|
+
};
|
|
269
|
+
/**
|
|
270
|
+
* @typedef {string | string[]} CorsValue
|
|
271
|
+
* @description CORS settings array or single one string.
|
|
272
|
+
*/
|
|
273
|
+
export type CorsValue = string | string[];
|
|
274
|
+
/**
|
|
275
|
+
* @interface CorsConfig
|
|
276
|
+
* @description Configuration necessary for CORS settings.
|
|
277
|
+
* The fields directly map to the corresponding Access-Control-... response headers.
|
|
278
|
+
*/
|
|
279
|
+
export interface CorsConfig {
|
|
280
|
+
/**
|
|
281
|
+
* Maps to 'Access-Control-Allow-Origin'.
|
|
282
|
+
* Can be a single origin string, an array of origins, or boolean 'true' for '*' (wildcard).
|
|
283
|
+
*/
|
|
284
|
+
allowedOrigins?: CorsValue | boolean;
|
|
285
|
+
/**
|
|
286
|
+
* Maps to 'Access-Control-Allow-Methods'.
|
|
287
|
+
*/
|
|
288
|
+
allowedMethods?: CorsValue;
|
|
289
|
+
/**
|
|
290
|
+
* Maps to 'Access-Control-Allow-Headers'.
|
|
291
|
+
*/
|
|
292
|
+
allowedHeaders?: CorsValue;
|
|
293
|
+
/**
|
|
294
|
+
* Maps to 'Access-Control-Expose-Headers'.
|
|
295
|
+
*/
|
|
296
|
+
exposedHeaders?: CorsValue;
|
|
297
|
+
/**
|
|
298
|
+
* Maps to 'Access-Control-Allow-Credentials'.
|
|
299
|
+
*/
|
|
300
|
+
credentials?: boolean;
|
|
301
|
+
/**
|
|
302
|
+
* Maps to 'Access-Control-Max-Age'.
|
|
303
|
+
*/
|
|
304
|
+
maxAge?: number;
|
|
305
|
+
}
|
|
306
|
+
/**
|
|
307
|
+
* @interface ServerOptions
|
|
308
|
+
* @description Options used to configure the behavior of the Http server.
|
|
309
|
+
* @property {net.ServerOpts} netServerOptions - Options passed to the underlying Node.js net.Server structure.
|
|
310
|
+
* @property {number} [maxHeaderSize=2048] - The maximum allowed request header size (bytes). (Recommended: 2048 - 4096)
|
|
311
|
+
* @property {number} [maxContentSize=3145728] - The maximum allowed request content/payload size (bytes). (Recommended: 1MB - 10MB)
|
|
312
|
+
* @property {number} [timeout=0] - Socket timeout duration (milliseconds). (3000: No timeout)
|
|
313
|
+
* @property {boolean} [untilEnd=false] - Determines if the server should wait for the end of the stream when Content-Length or Transfer-Encoding are not specified.
|
|
314
|
+
* If `false` and these headers are missing, the request is closed immediately and ignored (Default behavior).
|
|
315
|
+
* If `true`, it waits until the end of the stream.
|
|
316
|
+
* @property {number} [maxRequests=5000] - The maximum number of simultaneous requests/connections that can be processed. Also determines the pool size. (Recommended: 5000 - 10000)
|
|
317
|
+
* @property {typeof PipeResponseBase} ResponseCtor - The constructor function for the custom Response class to be used for requests.
|
|
318
|
+
* Can be used by extending `PipeResponseBase` to add your own custom response types (e.g., for JSON, XML, etc.).
|
|
319
|
+
* @property {number} [requestQuerySize=2048] - The maximum allowed request query string size (bytes). (Recommended: 1024 - 4096)
|
|
320
|
+
*/
|
|
321
|
+
export interface ServerOptions {
|
|
322
|
+
netServerOptions?: net.ServerOpts;
|
|
323
|
+
maxHeaderSize?: number;
|
|
324
|
+
maxHeaderNameSize?: number;
|
|
325
|
+
maxHeaderValueSize?: number;
|
|
326
|
+
maxContentSize?: number;
|
|
327
|
+
timeout?: number;
|
|
328
|
+
untilEnd?: boolean;
|
|
329
|
+
maxRequests?: number;
|
|
330
|
+
ResponseCtor?: typeof PipeResponseBase;
|
|
331
|
+
bootstrapPoolChunkProgression?: (createdChunkProgression: ChunkProgression) => void;
|
|
332
|
+
requestQuerySize?: number;
|
|
333
|
+
}
|
|
334
|
+
/**
|
|
335
|
+
* @interface ServerState
|
|
336
|
+
* @description Holds the runtime configuration state of the server.
|
|
337
|
+
* @property {string} corsHeaders - The pre-built string of CORS response headers.
|
|
338
|
+
* @property {number} maxHeaderNameSize - The maximum allowed request header name size (bytes).
|
|
339
|
+
* @property {number} maxHeaderValueSize - The maximum allowed request header value size (bytes).
|
|
340
|
+
* @property {number} maxContentSize - The maximum allowed request body size (bytes).
|
|
341
|
+
* @property {number} timeout - The socket timeout duration (milliseconds).
|
|
342
|
+
* @property {boolean} untilEnd - Whether to wait until the end of the stream when Content-Length/Transfer-Encoding is missing.
|
|
343
|
+
* @property {number} requestQuerySize - Request Query Size
|
|
344
|
+
* @property {number} maxRequests - Max requests
|
|
345
|
+
* @property {typeof PipeResponseBase} ResponseCtor - The constructor function of the Response class in use.
|
|
346
|
+
*/
|
|
347
|
+
export interface ServerState {
|
|
348
|
+
corsHeaders: string;
|
|
349
|
+
maxHeaderSize: number;
|
|
350
|
+
maxHeaderNameSize: number;
|
|
351
|
+
maxHeaderValueSize: number;
|
|
352
|
+
maxContentSize: number;
|
|
353
|
+
timeout: number;
|
|
354
|
+
untilEnd: boolean;
|
|
355
|
+
requestQuerySize: number;
|
|
356
|
+
maxRequests: number;
|
|
357
|
+
ResponseCtor: typeof PipeResponseBase;
|
|
358
|
+
}
|
|
359
|
+
export interface Middleware {
|
|
360
|
+
handle: MiddlewareHandleFn;
|
|
361
|
+
}
|
|
362
|
+
export type AccumulateHandleFn = (socket: net.Socket, p: ChunkProgression) => void;
|
|
363
|
+
export interface Endpoint {
|
|
364
|
+
url: string;
|
|
365
|
+
method: HttpMethod;
|
|
366
|
+
ct?: ContentConfig;
|
|
367
|
+
accumulateHandle?: AccumulateHandleFn;
|
|
368
|
+
middlewares: Middleware[];
|
|
369
|
+
addMiddleware(mw: Middleware): Endpoint;
|
|
370
|
+
handle: EndpointHandleFn | any;
|
|
371
|
+
untilEnd?: boolean;
|
|
372
|
+
maxContentSize?: number;
|
|
373
|
+
maxHeaderSize?: number;
|
|
374
|
+
}
|
|
375
|
+
export interface EndpointOpt {
|
|
376
|
+
untilEnd?: boolean;
|
|
377
|
+
maxContentSize?: number;
|
|
378
|
+
maxHeaderSize?: number;
|
|
379
|
+
}
|
|
380
|
+
/**
|
|
381
|
+
* @interface Route
|
|
382
|
+
* @description Defines a routing structure for the Http server.
|
|
383
|
+
* It is the basic building block of the routing tree.
|
|
384
|
+
* @property {string} url - The URL path segment this route will match (e.g., '/users').
|
|
385
|
+
* @property {Endpoint[]} endpoints - Endpoints corresponding to HTTP methods for this route.
|
|
386
|
+
* @property {Middleware[]} middlewares - Middleware functions to run for requests to this route and its sub-routes.
|
|
387
|
+
* @property {Route[]} routes - Nested sub-routes under this route.
|
|
388
|
+
* @method addRoute - Adds a new sub-route.
|
|
389
|
+
* @method addEndpoint - Adds a new endpoint.
|
|
390
|
+
* @method addMiddleware - Adds a new middleware.
|
|
391
|
+
*/
|
|
392
|
+
export interface Route {
|
|
393
|
+
url: string;
|
|
394
|
+
endpoints: Endpoint[];
|
|
395
|
+
middlewares: Middleware[];
|
|
396
|
+
routes: Route[];
|
|
397
|
+
addRoute(r: Route): Route;
|
|
398
|
+
addEndpoint(ep: Endpoint): Route;
|
|
399
|
+
addMiddleware(mw: Middleware): Route;
|
|
400
|
+
}
|
|
401
|
+
export interface BuildedRoute {
|
|
402
|
+
method: string;
|
|
403
|
+
route: string;
|
|
404
|
+
vptrTableIndex: number;
|
|
405
|
+
}
|
|
406
|
+
export interface Accumulate {
|
|
407
|
+
handle: Function;
|
|
408
|
+
}
|
|
409
|
+
export type CompressionFn = (b: Buffer) => Buffer | null;
|
|
410
|
+
export type DecompressionFn = (b: Buffer) => Buffer | null;
|
|
411
|
+
export interface ContentDecoding {
|
|
412
|
+
gzip?: DecompressionFn;
|
|
413
|
+
br?: DecompressionFn;
|
|
414
|
+
deflate?: DecompressionFn;
|
|
415
|
+
}
|
|
416
|
+
export interface ContentEncoding {
|
|
417
|
+
gzip?: CompressionFn;
|
|
418
|
+
br?: CompressionFn;
|
|
419
|
+
deflate?: CompressionFn;
|
|
420
|
+
}
|
|
421
|
+
export type BodyParserFn = (b: Buffer) => Buffer | null;
|
|
422
|
+
export type ContentTypeParser = {
|
|
423
|
+
[K in ContentTypeTables]?: BodyParserFn | null;
|
|
424
|
+
} & {
|
|
425
|
+
[key: string]: BodyParserFn | null | undefined;
|
|
426
|
+
};
|
|
427
|
+
enum ContentTypeTables {
|
|
428
|
+
JSON = "application/json",
|
|
429
|
+
URL_ENCODED_FORM = "application/x-www-form-urlencoded",
|
|
430
|
+
MULTIPART_FORM = "multipart/form-data",
|
|
431
|
+
TEXT_PLAIN = "text/plain",
|
|
432
|
+
HTML = "text/html",
|
|
433
|
+
CSS = "text/css",
|
|
434
|
+
JAVASCRIPT = "application/javascript",
|
|
435
|
+
OCTET_STREAM = "application/octet-stream",
|
|
436
|
+
XML = "application/xml"
|
|
437
|
+
}
|
|
438
|
+
export enum ContentEncodingTables {
|
|
439
|
+
gzip = "gzip",
|
|
440
|
+
br = "br",
|
|
441
|
+
deflate = "deflate"
|
|
442
|
+
}
|
|
443
|
+
export interface ContentConfig {
|
|
444
|
+
type: ContentTypeTables | null | undefined;
|
|
445
|
+
encoding: ContentEncodingTables | null | undefined;
|
|
446
|
+
}
|
|
447
|
+
export interface RoutePipe {
|
|
448
|
+
accumulateHandler(socket: net.Socket, chunkProgression: ChunkProgression): void;
|
|
449
|
+
url: string;
|
|
450
|
+
ct?: ContentConfig;
|
|
451
|
+
pipeHandler: Function;
|
|
452
|
+
mws: Http.MiddlewareHandleFn[];
|
|
453
|
+
ResponseCtor: typeof PipeResponseBase;
|
|
454
|
+
routeId: number;
|
|
455
|
+
untilEnd: boolean;
|
|
456
|
+
maxContentSize: number;
|
|
457
|
+
maxHeaderSize: number;
|
|
458
|
+
}
|
|
459
|
+
export type ParseInitialFn = (socket: net.Socket, chunk: Buffer, p: Http.ChunkProgression) => void;
|
|
460
|
+
export interface WebContextState {
|
|
461
|
+
publicStaticPath?: string;
|
|
462
|
+
publicStaticRoute?: string;
|
|
463
|
+
spaRootPath?: string;
|
|
464
|
+
}
|
|
465
|
+
/**
|
|
466
|
+
* @interface ChunkProgression
|
|
467
|
+
* @description Represents the state and context of a single HTTP request connection (socket) as it is being parsed.
|
|
468
|
+
* It manages the progression through the request parsing stages (request line, headers, body).
|
|
469
|
+
*/
|
|
470
|
+
export interface ChunkProgression {
|
|
471
|
+
/**
|
|
472
|
+
* @method fn
|
|
473
|
+
* @description The current parsing function to be executed when new data (chunk) arrives on the socket.
|
|
474
|
+
* This function changes based on the request parsing state (e.g., from `parseInitial` to `parseHeader`, etc.).
|
|
475
|
+
* @param {net.Socket} socket - The active network socket connection.
|
|
476
|
+
* @param {Buffer} chunk - The newly received data buffer.
|
|
477
|
+
* @param {Http.ChunkProgression} chunkProgression - A self-reference to the current state object.
|
|
478
|
+
*/
|
|
479
|
+
fn: ParseInitialFn;
|
|
480
|
+
/**
|
|
481
|
+
* @method free
|
|
482
|
+
* @description Releases this ChunkProgression object back to its object pool (`cPool`) for reuse.
|
|
483
|
+
* This is crucial for performance and memory management (pooling strategy).
|
|
484
|
+
*/
|
|
485
|
+
free(): void;
|
|
486
|
+
/**
|
|
487
|
+
* @method reset
|
|
488
|
+
* @description Resets all internal fields and properties to their initial state, preparing the object for a new incoming request.
|
|
489
|
+
*/
|
|
490
|
+
reset(): void;
|
|
491
|
+
/**
|
|
492
|
+
* @method allocateResp
|
|
493
|
+
* @description Allocates a pre-initialized `PipeResponseBase` object from the response pool for the current request.
|
|
494
|
+
* @returns {PipeResponseBase} A reusable response object.
|
|
495
|
+
*/
|
|
496
|
+
allocateResp(): PipeResponseBase;
|
|
497
|
+
/**
|
|
498
|
+
* @property {number} objId
|
|
499
|
+
* @description The unique identifier of this object within its associated object pool.
|
|
500
|
+
* This ID is necessary for the `free()` method to return the object to the correct pool slot.
|
|
501
|
+
*/
|
|
502
|
+
objId: number;
|
|
503
|
+
/**
|
|
504
|
+
* @property {Record<string, string>} headers
|
|
505
|
+
* @description A map containing the parsed HTTP request headers (key-value pairs).
|
|
506
|
+
*/
|
|
507
|
+
headers: Record<string, string>;
|
|
508
|
+
/**
|
|
509
|
+
* @property {number} headerSize
|
|
510
|
+
* @description The size, in bytes, of the currently accumulated raw header data.
|
|
511
|
+
* Used primarily during multi-chunk header parsing to track progress against `maxHeaderSize`.
|
|
512
|
+
*/
|
|
513
|
+
headerSize: number;
|
|
514
|
+
/**
|
|
515
|
+
* @property {RoutePipe} routePipe
|
|
516
|
+
* @description A reference to the specific route/endpoint handler object (`RoutePipe`) matched by the request URL and method.
|
|
517
|
+
* It points to the function chain that will process the request.
|
|
518
|
+
*/
|
|
519
|
+
routePipe: RoutePipe;
|
|
520
|
+
/**
|
|
521
|
+
* @property {string[]} params
|
|
522
|
+
* @description An array of values extracted from the URL path as route parameters (e.g., `/users/:id` extracts `id`'s value).
|
|
523
|
+
*/
|
|
524
|
+
params: string[];
|
|
525
|
+
/**
|
|
526
|
+
* @property {Record<string, string>} query
|
|
527
|
+
* @description A map containing the parsed URL query string parameters (e.g., `?a=1&b=2`).
|
|
528
|
+
*/
|
|
529
|
+
query: Record<string, string>;
|
|
530
|
+
/**
|
|
531
|
+
* @property {RetFlagBits} retFlag
|
|
532
|
+
* @description A flag indicating the result of the last parsing operation.
|
|
533
|
+
* Used to signal various states, including successful parsing (`OK`) or specific error conditions (e.g., `NOT_FOUND`, `MAX_HEADER_SIZE`).
|
|
534
|
+
*/
|
|
535
|
+
retFlag: RetFlagBits;
|
|
536
|
+
/**
|
|
537
|
+
* @property {HttpMethod} method
|
|
538
|
+
* @description The HTTP method of the current request (e.g., GET, POST, PUT).
|
|
539
|
+
*/
|
|
540
|
+
method: HttpMethod;
|
|
541
|
+
/**
|
|
542
|
+
* @property {number} mainOffset
|
|
543
|
+
* @description The byte offset within `rawBuf` where the **request body** begins (i.e., immediately after the double CRLF following the headers).
|
|
544
|
+
* This is essential for separating headers from body data.
|
|
545
|
+
*/
|
|
546
|
+
mainOffset: number;
|
|
547
|
+
/**
|
|
548
|
+
* @property {number | undefined} contentLen
|
|
549
|
+
* @description The expected length of the request body, as indicated by the 'Content-Length' header.
|
|
550
|
+
* Undefined if the header is not present.
|
|
551
|
+
*/
|
|
552
|
+
contentLen: number | undefined;
|
|
553
|
+
/**
|
|
554
|
+
* @property {Buffer} rawBuf
|
|
555
|
+
* @description A buffer holding the raw incoming request data, including the request line and headers.
|
|
556
|
+
* If the headers and body arrive in the same chunk, `rawBuf` will contain the body part as well until it is fully processed.
|
|
557
|
+
*/
|
|
558
|
+
rawBuf: Buffer;
|
|
559
|
+
/**
|
|
560
|
+
* @property {ChunkParser} chunkParser
|
|
561
|
+
* @description An internal object responsible for parsing chunked transfer encoding body data.
|
|
562
|
+
* Only used when the request uses 'Transfer-Encoding: chunked'.
|
|
563
|
+
*/
|
|
564
|
+
chunkParser: ChunkParser;
|
|
565
|
+
}
|
|
566
|
+
export {};
|
|
567
|
+
}
|
package/dist/http.js
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Http = void 0;
|
|
4
|
+
var Http;
|
|
5
|
+
(function (Http) {
|
|
6
|
+
let HttpMethod;
|
|
7
|
+
(function (HttpMethod) {
|
|
8
|
+
HttpMethod[HttpMethod["HEAD"] = 0] = "HEAD";
|
|
9
|
+
HttpMethod[HttpMethod["GET"] = 1] = "GET";
|
|
10
|
+
HttpMethod[HttpMethod["POST"] = 2] = "POST";
|
|
11
|
+
HttpMethod[HttpMethod["PUT"] = 3] = "PUT";
|
|
12
|
+
HttpMethod[HttpMethod["DELETE"] = 4] = "DELETE";
|
|
13
|
+
HttpMethod[HttpMethod["PATCH"] = 5] = "PATCH";
|
|
14
|
+
HttpMethod[HttpMethod["OPTIONS"] = 6] = "OPTIONS";
|
|
15
|
+
})(HttpMethod = Http.HttpMethod || (Http.HttpMethod = {}));
|
|
16
|
+
let RetFlagBits;
|
|
17
|
+
(function (RetFlagBits) {
|
|
18
|
+
RetFlagBits[RetFlagBits["FLAG_OK"] = 0] = "FLAG_OK";
|
|
19
|
+
RetFlagBits[RetFlagBits["FLAG_BAD_REQUEST"] = 1] = "FLAG_BAD_REQUEST";
|
|
20
|
+
RetFlagBits[RetFlagBits["FLAG_METHOD_NOT_ALLOWED"] = 2] = "FLAG_METHOD_NOT_ALLOWED";
|
|
21
|
+
RetFlagBits[RetFlagBits["FLAG_NOT_FOUND"] = 4] = "FLAG_NOT_FOUND";
|
|
22
|
+
RetFlagBits[RetFlagBits["FLAG_CORS_PREFLIGHT"] = 8] = "FLAG_CORS_PREFLIGHT";
|
|
23
|
+
RetFlagBits[RetFlagBits["FLAG_HTTP_VERSION_UNSUPPORTED"] = 16] = "FLAG_HTTP_VERSION_UNSUPPORTED";
|
|
24
|
+
RetFlagBits[RetFlagBits["FLAG_CONTENT_LENGTH_TOO_LARGE"] = 32] = "FLAG_CONTENT_LENGTH_TOO_LARGE";
|
|
25
|
+
RetFlagBits[RetFlagBits["FLAG_MISSING_HOST"] = 64] = "FLAG_MISSING_HOST";
|
|
26
|
+
RetFlagBits[RetFlagBits["FLAG_HAS_BODY"] = 128] = "FLAG_HAS_BODY";
|
|
27
|
+
RetFlagBits[RetFlagBits["FLAG_INVALID_ARGUMENT"] = 256] = "FLAG_INVALID_ARGUMENT";
|
|
28
|
+
RetFlagBits[RetFlagBits["FLAG_INVALID_HEADER"] = 512] = "FLAG_INVALID_HEADER";
|
|
29
|
+
RetFlagBits[RetFlagBits["FLAG_INVALID_HEADER_VALUE"] = 768] = "FLAG_INVALID_HEADER_VALUE";
|
|
30
|
+
RetFlagBits[RetFlagBits["FLAG_INVALID_CONTENT_LENGTH"] = 1024] = "FLAG_INVALID_CONTENT_LENGTH";
|
|
31
|
+
RetFlagBits[RetFlagBits["FLAG_CONTENT_LENGTH_EXCEEDED"] = 2048] = "FLAG_CONTENT_LENGTH_EXCEEDED";
|
|
32
|
+
RetFlagBits[RetFlagBits["FLAG_UNTERMINATED_HEADERS"] = 4096] = "FLAG_UNTERMINATED_HEADERS";
|
|
33
|
+
RetFlagBits[RetFlagBits["FLAG_MAX_HEADER_SIZE"] = 8192] = "FLAG_MAX_HEADER_SIZE";
|
|
34
|
+
RetFlagBits[RetFlagBits["FLAG_MAX_HEADER_NAME_SIZE"] = 8448] = "FLAG_MAX_HEADER_NAME_SIZE";
|
|
35
|
+
RetFlagBits[RetFlagBits["FLAG_MAX_HEADER_VALUE_SIZE"] = 8704] = "FLAG_MAX_HEADER_VALUE_SIZE";
|
|
36
|
+
RetFlagBits[RetFlagBits["FLAG_DUPLICATE_SINGLE_HEADER"] = 12288] = "FLAG_DUPLICATE_SINGLE_HEADER";
|
|
37
|
+
RetFlagBits[RetFlagBits["FLAG_REQUEST_QUERY_EXCEEDED"] = 16384] = "FLAG_REQUEST_QUERY_EXCEEDED";
|
|
38
|
+
RetFlagBits[RetFlagBits["FLAG_REQUEST_URL_EXCEEDED"] = 20480] = "FLAG_REQUEST_URL_EXCEEDED";
|
|
39
|
+
RetFlagBits[RetFlagBits["FLAG_SMUGGING_TE_CL"] = 24576] = "FLAG_SMUGGING_TE_CL";
|
|
40
|
+
})(RetFlagBits = Http.RetFlagBits || (Http.RetFlagBits = {}));
|
|
41
|
+
let ContentTypeTables;
|
|
42
|
+
(function (ContentTypeTables) {
|
|
43
|
+
ContentTypeTables["JSON"] = "application/json";
|
|
44
|
+
ContentTypeTables["URL_ENCODED_FORM"] = "application/x-www-form-urlencoded";
|
|
45
|
+
ContentTypeTables["MULTIPART_FORM"] = "multipart/form-data";
|
|
46
|
+
ContentTypeTables["TEXT_PLAIN"] = "text/plain";
|
|
47
|
+
ContentTypeTables["HTML"] = "text/html";
|
|
48
|
+
ContentTypeTables["CSS"] = "text/css";
|
|
49
|
+
ContentTypeTables["JAVASCRIPT"] = "application/javascript";
|
|
50
|
+
ContentTypeTables["OCTET_STREAM"] = "application/octet-stream";
|
|
51
|
+
ContentTypeTables["XML"] = "application/xml";
|
|
52
|
+
})(ContentTypeTables || (ContentTypeTables = {}));
|
|
53
|
+
let ContentEncodingTables;
|
|
54
|
+
(function (ContentEncodingTables) {
|
|
55
|
+
ContentEncodingTables["gzip"] = "gzip";
|
|
56
|
+
ContentEncodingTables["br"] = "br";
|
|
57
|
+
ContentEncodingTables["deflate"] = "deflate";
|
|
58
|
+
})(ContentEncodingTables = Http.ContentEncodingTables || (Http.ContentEncodingTables = {}));
|
|
59
|
+
})(Http || (exports.Http = Http = {}));
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { Http } from "./http";
|
|
2
|
+
export interface IHttpCore {
|
|
3
|
+
registerRoutes(routes: Http.BuildedRoute[]): any;
|
|
4
|
+
scannerRouteFirst(buffer: Buffer, reqObj: Http.ChunkProgression, maxHeaderNameSize: number, maxHeaderValueSize: number, maxContentLength: number, queryLimit: number): number;
|
|
5
|
+
scannerHeader(buffer: Buffer, reqObj: Http.ChunkProgression, maxHeaderNameSize: number, maxHeaderValueSize: number, maxContentLength: number): void;
|
|
6
|
+
printRouteTree(deepth: number): void;
|
|
7
|
+
}
|
|
8
|
+
export interface ICPool {
|
|
9
|
+
initializePool(size: number): void;
|
|
10
|
+
registerObj(obj: object): number;
|
|
11
|
+
allocate(): any | null;
|
|
12
|
+
free(index: number): void;
|
|
13
|
+
resizePool(newSize: number): void;
|
|
14
|
+
}
|
|
15
|
+
export interface IPublicAssetParser {
|
|
16
|
+
setAssetRoute(publicPath: string): void;
|
|
17
|
+
handlePublicAsset(curl: Buffer, offset: number): string;
|
|
18
|
+
}
|
|
19
|
+
export interface HypernodeAddon {
|
|
20
|
+
HttpCore: {
|
|
21
|
+
new (): IHttpCore;
|
|
22
|
+
};
|
|
23
|
+
CPool: {
|
|
24
|
+
new (): ICPool;
|
|
25
|
+
};
|
|
26
|
+
PublicAssetParser: {
|
|
27
|
+
new (): IPublicAssetParser;
|
|
28
|
+
};
|
|
29
|
+
scanUrl(curl: Buffer, offset: number): string;
|
|
30
|
+
}
|
|
31
|
+
export declare const hypernode: HypernodeAddon;
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.hypernode = void 0;
|
|
7
|
+
const bindings_1 = __importDefault(require("bindings"));
|
|
8
|
+
exports.hypernode = (0, bindings_1.default)("hypernode");
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { Http } from "./http";
|
|
2
|
+
import WebContext from "./http/context/WebContext";
|
|
3
|
+
import ApiContext from "./http/context/ApiContext";
|
|
4
|
+
declare function createServer(opts?: Http.ServerOptions): {
|
|
5
|
+
Web(webCtxOpts: Http.WebContextState, mainRoute?: Http.Route): WebContext;
|
|
6
|
+
Api(mainRoute: Http.Route): ApiContext;
|
|
7
|
+
};
|
|
8
|
+
export { createServer };
|
|
9
|
+
export * from "./http";
|