web-listener 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 +45 -0
- package/README.md +168 -0
- package/index.d.ts +1147 -0
- package/index.js +1 -0
- package/package.json +28 -0
- package/run.js +2 -0
package/index.d.ts
ADDED
|
@@ -0,0 +1,1147 @@
|
|
|
1
|
+
import { IncomingMessage, ServerResponse, RequestListener, Server, ServerOptions, OutgoingHttpHeaders, IncomingHttpHeaders, Agent } from 'node:http';
|
|
2
|
+
import { Duplex, Readable, Writable } from 'node:stream';
|
|
3
|
+
import { AddressInfo } from 'node:net';
|
|
4
|
+
import { Stats } from 'node:fs';
|
|
5
|
+
import { FileHandle } from 'node:fs/promises';
|
|
6
|
+
import { ReadableStream, TextDecoderOptions, TransformStream } from 'node:stream/web';
|
|
7
|
+
import { AgentOptions, Agent as Agent$1 } from 'node:https';
|
|
8
|
+
|
|
9
|
+
type ClientErrorListener = (err: Error, socket: Duplex) => void;
|
|
10
|
+
type UpgradeListener = (req: IncomingMessage, socket: Duplex, head: Buffer) => void;
|
|
11
|
+
type ShouldUpgradeCallback = (req: IncomingMessage) => boolean;
|
|
12
|
+
|
|
13
|
+
interface Address {
|
|
14
|
+
type: 'IPv4' | 'IPv6' | 'alias';
|
|
15
|
+
ip: string;
|
|
16
|
+
port: number | undefined;
|
|
17
|
+
}
|
|
18
|
+
declare function parseAddress(address: string | undefined): Address | undefined;
|
|
19
|
+
declare function makeAddressTester(cidrRanges: string[]): (address: Address | undefined) => boolean;
|
|
20
|
+
|
|
21
|
+
declare class BlockingQueue<T> {
|
|
22
|
+
constructor();
|
|
23
|
+
push(value: T): void;
|
|
24
|
+
shift(timeout?: number | undefined): Promise<T>;
|
|
25
|
+
close(reason: unknown): void;
|
|
26
|
+
fail(reason: unknown): void;
|
|
27
|
+
[Symbol.asyncIterator](): AsyncIterator<T, unknown, undefined>;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
declare function findCause<T>(error: unknown, errorType: {
|
|
31
|
+
new (...args: any[]): T;
|
|
32
|
+
}): T | undefined;
|
|
33
|
+
|
|
34
|
+
declare function getAddressURL(address: string | AddressInfo | null | undefined): string;
|
|
35
|
+
|
|
36
|
+
declare class Queue<T> {
|
|
37
|
+
constructor(initialItem?: T);
|
|
38
|
+
isEmpty(): boolean;
|
|
39
|
+
clear(): void;
|
|
40
|
+
push(item: T): void;
|
|
41
|
+
shift(): T | null;
|
|
42
|
+
remove(item: T): void;
|
|
43
|
+
[Symbol.iterator](): Iterator<T, unknown, undefined>;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
type UpgradeErrorHandler = (error: unknown, req: IncomingMessage, socket: Duplex) => void;
|
|
47
|
+
type ServerGeneralErrorCallback = (error: unknown, action: string, req?: IncomingMessage) => void;
|
|
48
|
+
type ServerErrorCallback = (error: unknown, action: string, req: IncomingMessage) => void;
|
|
49
|
+
|
|
50
|
+
type MaybePromise<T> = Promise<T> | T;
|
|
51
|
+
|
|
52
|
+
type SoftCloseHandler = (reason: string) => MaybePromise<void>;
|
|
53
|
+
declare function setSoftCloseHandler(req: IncomingMessage, fn: SoftCloseHandler): void;
|
|
54
|
+
declare const isSoftClosed: (req: IncomingMessage) => boolean;
|
|
55
|
+
declare const defer: (req: IncomingMessage, fn: () => MaybePromise<void>) => void;
|
|
56
|
+
declare const addTeardown: (req: IncomingMessage, fn: () => MaybePromise<void>) => void;
|
|
57
|
+
declare const getAbortSignal: (req: IncomingMessage) => AbortSignal;
|
|
58
|
+
|
|
59
|
+
type AcceptUpgradeHandler<T> = (...args: Parameters<UpgradeListener>) => Promise<AcceptUpgradeResult<T>>;
|
|
60
|
+
interface AcceptUpgradeResult<T> {
|
|
61
|
+
return: T;
|
|
62
|
+
onError: UpgradeErrorHandler;
|
|
63
|
+
softCloseHandler: SoftCloseHandler;
|
|
64
|
+
}
|
|
65
|
+
declare function acceptUpgrade<T>(req: IncomingMessage, upgrade: AcceptUpgradeHandler<T>): Promise<T>;
|
|
66
|
+
|
|
67
|
+
declare const PATH_PARAMETERS: unique symbol;
|
|
68
|
+
type WithPathParameters<PathParameters> = {
|
|
69
|
+
[PATH_PARAMETERS]: PathParameters;
|
|
70
|
+
};
|
|
71
|
+
type WithoutPathParameters = {
|
|
72
|
+
[PATH_PARAMETERS]?: {
|
|
73
|
+
[k in PropertyKey]?: never;
|
|
74
|
+
};
|
|
75
|
+
};
|
|
76
|
+
declare function getPathParameters<PathParameters extends {}>(req: IncomingMessage & WithPathParameters<PathParameters>): Readonly<PathParameters>;
|
|
77
|
+
declare const getPathParameter: <PathParameters extends {}, ID extends keyof PathParameters>(req: IncomingMessage & WithPathParameters<PathParameters>, id: ID) => Readonly<PathParameters>[ID];
|
|
78
|
+
declare function getAbsolutePath(req: IncomingMessage): string;
|
|
79
|
+
declare function restoreAbsolutePath(req: IncomingMessage): void;
|
|
80
|
+
|
|
81
|
+
declare class RoutingInstruction extends Error {
|
|
82
|
+
}
|
|
83
|
+
declare const STOP: RoutingInstruction;
|
|
84
|
+
declare const CONTINUE: RoutingInstruction;
|
|
85
|
+
declare const NEXT_ROUTE: RoutingInstruction;
|
|
86
|
+
declare const NEXT_ROUTER: RoutingInstruction;
|
|
87
|
+
|
|
88
|
+
type ReturnHandlerParameter = object | null | undefined;
|
|
89
|
+
type HandlerResult = void | null | undefined | typeof STOP | typeof CONTINUE | typeof NEXT_ROUTE | typeof NEXT_ROUTER | ReturnHandlerParameter;
|
|
90
|
+
type RequestHandlerFn<Req = {}> = (req: IncomingMessage & Req, res: ServerResponse) => MaybePromise<HandlerResult>;
|
|
91
|
+
interface RequestHandler<Req = {}> {
|
|
92
|
+
handleRequest: RequestHandlerFn<Req>;
|
|
93
|
+
}
|
|
94
|
+
declare const requestHandler: <Req>(handler: RequestHandler<Req> | RequestHandlerFn<Req>) => RequestHandler<Req>;
|
|
95
|
+
type UpgradeHandlerFn<Req = {}> = (req: IncomingMessage & Req, socket: Duplex, head: Buffer) => MaybePromise<HandlerResult>;
|
|
96
|
+
type ShouldUpgradeFn<Req = {}> = (req: IncomingMessage & Req) => boolean;
|
|
97
|
+
interface UpgradeHandler<Req = {}> {
|
|
98
|
+
handleUpgrade: UpgradeHandlerFn<Req>;
|
|
99
|
+
shouldUpgrade?: ShouldUpgradeFn<Req> | undefined;
|
|
100
|
+
}
|
|
101
|
+
declare const upgradeHandler: <Req>(handler: UpgradeHandler<Req> | UpgradeHandlerFn<Req>, shouldUpgrade?: ShouldUpgradeFn<Req>) => UpgradeHandler<Req>;
|
|
102
|
+
declare const anyHandler: <Req>(handler: UpgradeHandlerFn<Req> & RequestHandlerFn<Req>, shouldUpgrade?: ShouldUpgradeFn<Req>) => RequestHandler<Req> & UpgradeHandler<Req>;
|
|
103
|
+
type ErrorHandlerFn<Req = {}> = (error: unknown, req: IncomingMessage & Req, output: {
|
|
104
|
+
response: ServerResponse;
|
|
105
|
+
socket?: never;
|
|
106
|
+
head?: never;
|
|
107
|
+
} | {
|
|
108
|
+
response?: never;
|
|
109
|
+
socket: Duplex;
|
|
110
|
+
head: Buffer;
|
|
111
|
+
}) => MaybePromise<HandlerResult>;
|
|
112
|
+
interface ErrorHandler<Req = {}> {
|
|
113
|
+
handleError: ErrorHandlerFn<Req>;
|
|
114
|
+
}
|
|
115
|
+
declare const errorHandler: <Req>(handler: ErrorHandler<Req> | ErrorHandlerFn<Req>) => ErrorHandler<Req>;
|
|
116
|
+
type Handler<Req = {}> = Partial<RequestHandler<Req> & UpgradeHandler<Req> & ErrorHandler<Req>>;
|
|
117
|
+
type RequestReturnHandlerFn<Req = {}> = (value: ReturnHandlerParameter, req: IncomingMessage & Req, res: ServerResponse) => MaybePromise<void>;
|
|
118
|
+
|
|
119
|
+
interface NativeListenersOptions {
|
|
120
|
+
onError?: ServerGeneralErrorCallback;
|
|
121
|
+
socketCloseTimeout?: number;
|
|
122
|
+
}
|
|
123
|
+
interface NativeListeners {
|
|
124
|
+
request: RequestListener;
|
|
125
|
+
upgrade: UpgradeListener;
|
|
126
|
+
shouldUpgrade: ShouldUpgradeCallback;
|
|
127
|
+
clientError: ClientErrorListener;
|
|
128
|
+
softClose(reason: string, onError: ServerErrorCallback, callback?: () => void): void;
|
|
129
|
+
hardClose(callback?: () => void): void;
|
|
130
|
+
countConnections(): number;
|
|
131
|
+
}
|
|
132
|
+
declare function toListeners(handler: Handler<WithoutPathParameters>, { onError, socketCloseTimeout }?: NativeListenersOptions): NativeListeners;
|
|
133
|
+
|
|
134
|
+
interface TypedEventTargetInstance<This, Mapping> extends EventTarget {
|
|
135
|
+
addEventListener<K extends keyof Mapping>(type: K, listener: (this: This, event: Mapping[K], options?: AddEventListenerOptions | boolean) => void): void;
|
|
136
|
+
addEventListener(type: string, callback: EventListenerOrEventListenerObject | null, options?: EventListenerOptions | boolean): void;
|
|
137
|
+
}
|
|
138
|
+
type TypedEventTarget<This, Mapping> = {
|
|
139
|
+
new (): TypedEventTargetInstance<This, Mapping>;
|
|
140
|
+
};
|
|
141
|
+
|
|
142
|
+
interface ListenOptions {
|
|
143
|
+
/**
|
|
144
|
+
* `backlog` parameter sent to `server.listen`.
|
|
145
|
+
*
|
|
146
|
+
* @default 511
|
|
147
|
+
*/
|
|
148
|
+
backlog?: number | undefined;
|
|
149
|
+
/**
|
|
150
|
+
* If given, this is passed to `server.timeout`. The number of milliseconds of inactivity before a socket is presumed to have timed out.
|
|
151
|
+
*/
|
|
152
|
+
socketTimeout?: number | undefined;
|
|
153
|
+
}
|
|
154
|
+
interface ListenerOptions extends Omit<NativeListenersOptions, 'onError'> {
|
|
155
|
+
/**
|
|
156
|
+
* Automatically send `417 Expectation Failed` for any request with a non-standard `Expect` header.
|
|
157
|
+
* Set to `false` to allow application-specific use of this header.
|
|
158
|
+
*
|
|
159
|
+
* @default true (matching Node.js behaviour)
|
|
160
|
+
*/
|
|
161
|
+
rejectNonStandardExpect?: boolean | undefined;
|
|
162
|
+
/**
|
|
163
|
+
* Automatically send `100 Continue` for any request with `Expect: 100-continue`.
|
|
164
|
+
* If set to `false`, all handlers MUST call `acceptBody(req)` before attempting
|
|
165
|
+
* to read the body of the request (bundled body parsing middleware does this
|
|
166
|
+
* automatically).
|
|
167
|
+
*
|
|
168
|
+
* @default true (matching Node.js behaviour)
|
|
169
|
+
*/
|
|
170
|
+
autoContinue?: boolean | undefined;
|
|
171
|
+
/**
|
|
172
|
+
* Override the shouldUpgradeCallback of the server with one that attempts to detect whether an
|
|
173
|
+
* upgrade request would be handled by the current routes. The detection does not invoke any
|
|
174
|
+
* handlers, but checks their `shouldUpgrade` function if it is present.
|
|
175
|
+
*
|
|
176
|
+
* @default true
|
|
177
|
+
*/
|
|
178
|
+
overrideShouldUpgradeCallback?: boolean | undefined;
|
|
179
|
+
}
|
|
180
|
+
type CombinedServerOptions = ServerOptions & ListenOptions & ListenerOptions;
|
|
181
|
+
declare const WebListener_base: TypedEventTarget<WebListener, {
|
|
182
|
+
error: CustomEvent<RequestErrorDetail>;
|
|
183
|
+
}>;
|
|
184
|
+
declare class WebListener extends WebListener_base {
|
|
185
|
+
constructor(handler: Handler<WithoutPathParameters>);
|
|
186
|
+
attach(server: Server, options?: ListenerOptions): (reason?: string, existingConnectionTimeout?: number, forceCloseAll?: boolean) => NativeListeners;
|
|
187
|
+
listen(port: number, host: string, options?: CombinedServerOptions): Promise<AugmentedServer>;
|
|
188
|
+
}
|
|
189
|
+
interface RequestErrorDetail {
|
|
190
|
+
error: unknown;
|
|
191
|
+
server: Server;
|
|
192
|
+
action: string;
|
|
193
|
+
request: IncomingMessage | undefined;
|
|
194
|
+
}
|
|
195
|
+
interface AugmentedServer extends Server {
|
|
196
|
+
closeWithTimeout(reason: string, timeout: number): Promise<void>;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
type MessageBody = string | Buffer | NodeJS.ArrayBufferView | ArrayBuffer | SharedArrayBuffer;
|
|
200
|
+
type AnyHeaders = HeadersInit | OutgoingHttpHeaders | Map<string, string | number | Readonly<string[]>> | undefined;
|
|
201
|
+
interface HTTPErrorOptions {
|
|
202
|
+
message?: string;
|
|
203
|
+
statusMessage?: string;
|
|
204
|
+
headers?: AnyHeaders;
|
|
205
|
+
body?: MessageBody;
|
|
206
|
+
cause?: unknown;
|
|
207
|
+
}
|
|
208
|
+
interface PartialServerResponse {
|
|
209
|
+
setHeaders(headers: Headers): void;
|
|
210
|
+
setHeader(name: string, value: string): void;
|
|
211
|
+
writeHead(status: number, message: string, extraHeaders?: OutgoingHttpHeaders): void;
|
|
212
|
+
end(chunk: MessageBody, encoding: BufferEncoding): void;
|
|
213
|
+
}
|
|
214
|
+
declare class HTTPError extends Error {
|
|
215
|
+
readonly statusCode: number;
|
|
216
|
+
readonly statusMessage: string;
|
|
217
|
+
readonly headers: AnyHeaders;
|
|
218
|
+
readonly body: MessageBody;
|
|
219
|
+
constructor(statusCode: number, { message, statusMessage, headers, body, ...options }?: HTTPErrorOptions);
|
|
220
|
+
static readonly INTERNAL_SERVER_ERROR: HTTPError;
|
|
221
|
+
send(res: PartialServerResponse, extraHeaders?: OutgoingHttpHeaders): void;
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
type ParameterPrefixes = [':', '*'];
|
|
225
|
+
type ParameterTerminators = ['/', '-', '.', ...ParameterPrefixes];
|
|
226
|
+
interface ParameterTypes {
|
|
227
|
+
':': string;
|
|
228
|
+
'*': string[];
|
|
229
|
+
}
|
|
230
|
+
type Resplit<S extends [string, string, string], D extends string> = S[0] extends `${infer A}${D}${infer B}` ? [A, D, `${B}${S[1]}${S[2]}`] : S;
|
|
231
|
+
type ResplitRecur<S extends [string, string, string], Ds extends string[]> = Ds extends [
|
|
232
|
+
infer D extends string,
|
|
233
|
+
...infer Rest extends string[]
|
|
234
|
+
] ? Resplit<ResplitRecur<S, Rest>, D> : S;
|
|
235
|
+
type SplitFirst<S extends string, Ds extends string[]> = ResplitRecur<[S, '', ''], Ds>;
|
|
236
|
+
type ReadParam<D, R extends [string, string, string]> = R[1] extends keyof ParameterTypes ? never : {
|
|
237
|
+
[k in R[0]]: D extends keyof ParameterTypes ? ParameterTypes[D] : never;
|
|
238
|
+
} & FindNextParam<SplitFirst<R[2], ParameterPrefixes>>;
|
|
239
|
+
type FindNextParam<S extends [string, string, string]> = S[1] extends '' ? {} : ReadParam<S[1], SplitFirst<S[2], ParameterTerminators>>;
|
|
240
|
+
type ReadParams<Path extends string> = FindNextParam<SplitFirst<Path, ParameterPrefixes>>;
|
|
241
|
+
type ParametersFromPath<Path extends string> = Path extends `${infer Start}{${infer Optional}}${infer Rest}` ? ReadParams<Start> & Partial<ReadParams<Optional>> & ParametersFromPath<Rest> : ReadParams<Path>;
|
|
242
|
+
|
|
243
|
+
declare const getSearch: (req: IncomingMessage) => string;
|
|
244
|
+
declare const getSearchParams: (req: IncomingMessage) => URLSearchParams;
|
|
245
|
+
declare const getQuery: (req: IncomingMessage, id: string) => string | null;
|
|
246
|
+
|
|
247
|
+
type CommonMethod = 'DELETE' | 'GET' | 'HEAD' | 'OPTIONS' | 'PATCH' | 'POST' | 'PUT' | 'TRACE';
|
|
248
|
+
type CommonUpgrade = 'http/2' | 'http/3' | 'https' | 'h2c' | 'websocket';
|
|
249
|
+
type RelaxedRequestHandler<Req = {}> = RequestHandlerFn<Req> | RequestHandler<Req> | ErrorHandler<Req>;
|
|
250
|
+
type RelaxedUpgradeHandler<Req = {}> = UpgradeHandlerFn<Req> | UpgradeHandler<Req> | ErrorHandler<Req>;
|
|
251
|
+
type MethodWrapper<Req, This> = <Path extends string>(path: Path, ...handlers: RelaxedRequestHandler<Req & WithPathParameters<ParametersFromPath<Path>>>[]) => This;
|
|
252
|
+
type UpgradeWrapper<Req, This> = <Path extends string>(path: Path, ...handlers: RelaxedUpgradeHandler<Req & WithPathParameters<ParametersFromPath<Path>>>[]) => This;
|
|
253
|
+
declare class Router<Req = {}> implements Required<Handler<Req>> {
|
|
254
|
+
constructor();
|
|
255
|
+
/**
|
|
256
|
+
* Register handlers or routers for all requests, upgrades, and errors, on all methods and paths.
|
|
257
|
+
*/
|
|
258
|
+
use(...handlers: Handler<Req>[]): this;
|
|
259
|
+
/**
|
|
260
|
+
* Register handlers or routers for all requests, upgrades, and errors, on all methods for all
|
|
261
|
+
* paths within the given path root.
|
|
262
|
+
*
|
|
263
|
+
* To register handlers at the path but not subpaths, use `.at` instead.
|
|
264
|
+
*/
|
|
265
|
+
mount<Path extends string>(path: Path, ...handlers: Handler<Req & WithPathParameters<ParametersFromPath<Path>>>[]): this;
|
|
266
|
+
/**
|
|
267
|
+
* Create a new router mounted at the path, and call the given function to configure it.
|
|
268
|
+
*/
|
|
269
|
+
within<Path extends string>(path: Path, init: (subRouter: Router<Req & WithPathParameters<ParametersFromPath<Path>>>) => void): this;
|
|
270
|
+
/**
|
|
271
|
+
* Register handlers or routers for all requests, upgrades, and errors, on all methods for a
|
|
272
|
+
* specific path.
|
|
273
|
+
*
|
|
274
|
+
* To register handlers at the path and all subpaths, use `.mount` instead.
|
|
275
|
+
*/
|
|
276
|
+
at<Path extends string>(path: Path, ...handlers: Handler<Req & WithPathParameters<ParametersFromPath<Path>>>[]): this;
|
|
277
|
+
/**
|
|
278
|
+
* Register handlers for requests or errors (not upgrades) on a specific method for a specific
|
|
279
|
+
* path.
|
|
280
|
+
*/
|
|
281
|
+
onRequest<Path extends string, Method extends string = CommonMethod>(method: Method | Iterable<Method>, path: Path, ...handlers: RelaxedRequestHandler<Req & WithPathParameters<ParametersFromPath<Path>>>[]): this;
|
|
282
|
+
/**
|
|
283
|
+
* Register handlers for upgrades or errors (not requests) on a specific method and protocol
|
|
284
|
+
* for a specific path.
|
|
285
|
+
*/
|
|
286
|
+
onUpgrade<Path extends string, Method extends string = CommonMethod, Protocol extends string = CommonUpgrade>(method: Method | Iterable<Method> | null, protocol: Protocol, path: Path, ...handlers: RelaxedUpgradeHandler<Req & WithPathParameters<ParametersFromPath<Path>>>[]): this;
|
|
287
|
+
/**
|
|
288
|
+
* Register error handlers.
|
|
289
|
+
*
|
|
290
|
+
* Error handlers are called if a request or upgrade handler which is before them in the chain
|
|
291
|
+
* throws. Error handlers can send a response and return to complete processing of the request.
|
|
292
|
+
* Error handlers can also return `CONTINUE` (or any other routing instruction) to pass control
|
|
293
|
+
* back to request or upgrade handlers. If an error handler throws, a combined error
|
|
294
|
+
* (`SuppressedError`) will be sent to the next error handler.
|
|
295
|
+
*/
|
|
296
|
+
onError(...handlers: (ErrorHandler<Req> | ErrorHandlerFn<Req>)[]): this;
|
|
297
|
+
/**
|
|
298
|
+
* Register return handlers.
|
|
299
|
+
*
|
|
300
|
+
* Return handlers are called if a request or error handler returns a value which is not a
|
|
301
|
+
* routing instruction. They can be used for features like templating or ensuring connections
|
|
302
|
+
* are always closed when a handler returns.
|
|
303
|
+
*
|
|
304
|
+
* Return hanlders are called in the order they were registered, and from the innermost router
|
|
305
|
+
* to the outermost rooter. Return handlers are not called for upgrade requests.
|
|
306
|
+
*
|
|
307
|
+
* Return handlers are not ordered with the other handlers, so they can be registered upfront if
|
|
308
|
+
* desired. If a return handler throws, the error will be passed to the next error handler after
|
|
309
|
+
* the request handler which triggered it.
|
|
310
|
+
*/
|
|
311
|
+
onReturn(...handlers: RequestReturnHandlerFn<Req>[]): this;
|
|
312
|
+
/**
|
|
313
|
+
* Convenience wrapper for `.onRequest`, accepting paths with a HTTP verb at the start (separated
|
|
314
|
+
* by a space).
|
|
315
|
+
*/
|
|
316
|
+
on<Path extends string>(path: `${CommonMethod} ${Path}`, ...handlers: RelaxedRequestHandler<Req & WithPathParameters<ParametersFromPath<Path>>>[]): this;
|
|
317
|
+
/**
|
|
318
|
+
* Registers handlers for GET requests at the given path. Note that these handlers will also
|
|
319
|
+
* be used for HEAD requests by default. To use different HEAD handling, you can register an
|
|
320
|
+
* explicit HEAD handler earlier in the router, or you can use `.getOnly` instead of `.get`.
|
|
321
|
+
*
|
|
322
|
+
* @param path
|
|
323
|
+
* @param handlers
|
|
324
|
+
* @returns
|
|
325
|
+
*/
|
|
326
|
+
get: MethodWrapper<Req, this>;
|
|
327
|
+
/** Alias for `onRequest('DELETE', path, ...handlers)` */
|
|
328
|
+
delete: MethodWrapper<Req, this>;
|
|
329
|
+
/**
|
|
330
|
+
* Alias for `onRequest('GET', path, ...handlers)`
|
|
331
|
+
*
|
|
332
|
+
* Unlike `.get`, this will _not_ also use the handler for HEAD requests.
|
|
333
|
+
*/
|
|
334
|
+
getOnly: MethodWrapper<Req, this>;
|
|
335
|
+
/** Alias for `onRequest('HEAD', path, ...handlers)` */
|
|
336
|
+
head: MethodWrapper<Req, this>;
|
|
337
|
+
/** Alias for `onRequest('OPTIONS', path, ...handlers)` */
|
|
338
|
+
options: MethodWrapper<Req, this>;
|
|
339
|
+
/** Alias for `onRequest('PATCH', path, ...handlers)` */
|
|
340
|
+
patch: MethodWrapper<Req, this>;
|
|
341
|
+
/** Alias for `onRequest('POST', path, ...handlers)` */
|
|
342
|
+
post: MethodWrapper<Req, this>;
|
|
343
|
+
/** Alias for `onRequest('PUT', path, ...handlers)` */
|
|
344
|
+
put: MethodWrapper<Req, this>;
|
|
345
|
+
/** Alias for `onUpgrade('GET', 'websocket', path, ...handlers)` */
|
|
346
|
+
ws: UpgradeWrapper<Req, this>;
|
|
347
|
+
/**
|
|
348
|
+
* Run routing on a request.
|
|
349
|
+
* The request must already be registered (i.e. have come through a WebListener).
|
|
350
|
+
*
|
|
351
|
+
* This can be used for complex custom sub-routing, but is otherwise not useful.
|
|
352
|
+
*
|
|
353
|
+
* To register an upgrade handler, use `.onRequest` or a convenience method.
|
|
354
|
+
*/
|
|
355
|
+
handleRequest(req: IncomingMessage & Req): Promise<HandlerResult>;
|
|
356
|
+
/**
|
|
357
|
+
* Run routing on an upgrade request.
|
|
358
|
+
* The request must already be registered (i.e. have come through a WebListener).
|
|
359
|
+
*
|
|
360
|
+
* This can be used for complex custom sub-routing, but is otherwise not useful.
|
|
361
|
+
*
|
|
362
|
+
* To register an upgrade handler, use `.onUpgrade` or a convenience method.
|
|
363
|
+
*/
|
|
364
|
+
handleUpgrade(req: IncomingMessage & Req): Promise<HandlerResult>;
|
|
365
|
+
/**
|
|
366
|
+
* Run routing on an error.
|
|
367
|
+
* The request must already be registered (i.e. have come through a WebListener).
|
|
368
|
+
*
|
|
369
|
+
* This can be used for complex custom sub-routing, but is otherwise not useful.
|
|
370
|
+
*
|
|
371
|
+
* To register an error handler, use `.onError`.
|
|
372
|
+
*/
|
|
373
|
+
handleError(error: unknown, req: IncomingMessage & Req): Promise<HandlerResult>;
|
|
374
|
+
shouldUpgrade(req: IncomingMessage & Req): boolean;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
interface BearerAuthOptions<Req, Token> {
|
|
378
|
+
realm: string | ((req: IncomingMessage & Req) => MaybePromise<string>);
|
|
379
|
+
extractAndValidateToken: (token: string, realm: string, req: IncomingMessage & Req) => MaybePromise<Token>;
|
|
380
|
+
fallbackTokenFetcher?: (req: IncomingMessage & Req) => MaybePromise<string | undefined>;
|
|
381
|
+
closeOnExpiry?: boolean;
|
|
382
|
+
softCloseBufferTime?: number;
|
|
383
|
+
onSoftCloseError?: ServerErrorCallback;
|
|
384
|
+
}
|
|
385
|
+
interface JWTToken {
|
|
386
|
+
nbf?: number;
|
|
387
|
+
exp?: number;
|
|
388
|
+
scopes?: Record<string, boolean> | string[] | string;
|
|
389
|
+
}
|
|
390
|
+
declare function requireBearerAuth<Req = {}, Token = JWTToken>({ realm, extractAndValidateToken, fallbackTokenFetcher, closeOnExpiry, softCloseBufferTime, onSoftCloseError, }: BearerAuthOptions<Req, Token>): RequestHandler<Req> & UpgradeHandler<Req>;
|
|
391
|
+
declare const getAuthData: <Token>(req: IncomingMessage) => Token | null;
|
|
392
|
+
declare const hasAuthScope: (req: IncomingMessage, scope: string) => boolean;
|
|
393
|
+
declare const requireAuthScope: (scope: string) => RequestHandler & UpgradeHandler;
|
|
394
|
+
|
|
395
|
+
declare function generateWeakETag(contentEncoding: string | number | string[] | undefined, stats: Pick<Stats, 'mtimeMs' | 'size'>): string;
|
|
396
|
+
declare function generateStrongETag(file: string | FileHandle): Promise<string>;
|
|
397
|
+
|
|
398
|
+
interface HTTPRange {
|
|
399
|
+
ranges: RangePart[];
|
|
400
|
+
totalSize?: number | undefined;
|
|
401
|
+
}
|
|
402
|
+
interface RangePart {
|
|
403
|
+
start: number;
|
|
404
|
+
end: number;
|
|
405
|
+
}
|
|
406
|
+
interface SimplifyRangeOptions {
|
|
407
|
+
forceSequential?: boolean;
|
|
408
|
+
mergeOverlapDistance?: number;
|
|
409
|
+
}
|
|
410
|
+
declare function simplifyRange(original: HTTPRange, { forceSequential, mergeOverlapDistance }?: SimplifyRangeOptions): HTTPRange;
|
|
411
|
+
|
|
412
|
+
declare function getAuthorization(req: IncomingMessage): [string, string] | undefined;
|
|
413
|
+
declare function getCharset(req: IncomingMessage): string | undefined;
|
|
414
|
+
declare function getIfRange(req: IncomingMessage): {
|
|
415
|
+
etag?: string[] | undefined;
|
|
416
|
+
modifiedSeconds?: number | undefined;
|
|
417
|
+
};
|
|
418
|
+
interface GetRangeOptions {
|
|
419
|
+
/**
|
|
420
|
+
* Maximum number of sequential, non-overlapping ranges a client can request in a
|
|
421
|
+
* single message.
|
|
422
|
+
*
|
|
423
|
+
* Typical browser clients only request a single range. In rare cases, clients may
|
|
424
|
+
* request 2 ranges. Bespoke clients may be able to make use of more ranges.
|
|
425
|
+
*
|
|
426
|
+
* @default 10
|
|
427
|
+
*/
|
|
428
|
+
maxRanges?: number;
|
|
429
|
+
/**
|
|
430
|
+
* Maximum number of ranges a client can request in a single message if any ranges are
|
|
431
|
+
* non-sequential (i.e. a later range begins at lower offset than an earlier range).
|
|
432
|
+
*
|
|
433
|
+
* As suggested in https://datatracker.ietf.org/doc/html/rfc7233, this uses a default
|
|
434
|
+
* limit of 2, as more ranges are likely to be a broken or malicious client.
|
|
435
|
+
*
|
|
436
|
+
* @default 2
|
|
437
|
+
*/
|
|
438
|
+
maxNonSequential?: number;
|
|
439
|
+
/**
|
|
440
|
+
* Maximum number of ranges a client can request in a single message if any ranges are
|
|
441
|
+
* overlapping.
|
|
442
|
+
*
|
|
443
|
+
* As suggested in https://datatracker.ietf.org/doc/html/rfc7233, this uses a default
|
|
444
|
+
* limit of 2, as more ranges are likely to be a broken or malicious client.
|
|
445
|
+
*
|
|
446
|
+
* @default 2
|
|
447
|
+
*/
|
|
448
|
+
maxWithOverlap?: number;
|
|
449
|
+
}
|
|
450
|
+
declare function getRange(req: IncomingMessage, totalSize: number, { maxRanges, maxNonSequential, maxWithOverlap }?: GetRangeOptions): HTTPRange | undefined;
|
|
451
|
+
interface QualityValue {
|
|
452
|
+
name: string;
|
|
453
|
+
specifiers: Map<string, string>;
|
|
454
|
+
specificity: number;
|
|
455
|
+
q: number;
|
|
456
|
+
}
|
|
457
|
+
declare function readHTTPUnquotedCommaSeparated(raw: LooseHeaderValue | undefined): string[] | undefined;
|
|
458
|
+
declare function readHTTPInteger(raw: string | undefined): number | undefined;
|
|
459
|
+
declare function readHTTPQualityValues(raw: string | undefined): QualityValue[] | undefined;
|
|
460
|
+
declare function readHTTPKeyValues(raw: string): Map<string, string>;
|
|
461
|
+
declare function readHTTPDateSeconds(raw: LooseHeaderValue | undefined): number | undefined;
|
|
462
|
+
type LooseHeaderValue = string | number | string[];
|
|
463
|
+
|
|
464
|
+
declare const HEADERS: {
|
|
465
|
+
mime: string;
|
|
466
|
+
language: string;
|
|
467
|
+
encoding: string;
|
|
468
|
+
};
|
|
469
|
+
type NegotiationType = keyof typeof HEADERS;
|
|
470
|
+
interface FileNegotiation {
|
|
471
|
+
type: NegotiationType;
|
|
472
|
+
options: FileNegotiationOption[];
|
|
473
|
+
}
|
|
474
|
+
interface FileNegotiationOption {
|
|
475
|
+
/**
|
|
476
|
+
* Value to match in `Accept-*` header.
|
|
477
|
+
* The comparison is case-insensitive.
|
|
478
|
+
*
|
|
479
|
+
* @example 'gzip'
|
|
480
|
+
* @example 'en-GB'
|
|
481
|
+
* @example /^en/
|
|
482
|
+
* @example 'text/html'
|
|
483
|
+
* @example /^text\//
|
|
484
|
+
*/
|
|
485
|
+
match: string | RegExp;
|
|
486
|
+
/**
|
|
487
|
+
* Override value to return in `Content-Type` or `Content-Encoding`.
|
|
488
|
+
* You can use this to give a concrete type when matching against a wildcard:
|
|
489
|
+
*
|
|
490
|
+
* @example { match: 'text/*', as: 'text/plain', file: '{base}.txt' }
|
|
491
|
+
*/
|
|
492
|
+
as?: string | undefined;
|
|
493
|
+
/**
|
|
494
|
+
* Filename modifier to apply. Several tokens are available:
|
|
495
|
+
*
|
|
496
|
+
* - `{file}` - the original filename (does not include the path)
|
|
497
|
+
* - `{base}` - the part of the original filename before the last `.` (or the entire filename if there is no dot)
|
|
498
|
+
* - `{ext}` - the original file extension, including the `.` (or blank of there is no dot)
|
|
499
|
+
*
|
|
500
|
+
* The resulting filename must not contain any path components (i.e. `/` and `\` are not allowed)
|
|
501
|
+
*
|
|
502
|
+
* @example '{file}.gz'
|
|
503
|
+
* @example '{base}-en{ext}'
|
|
504
|
+
* @example 'negotiated-{file}'
|
|
505
|
+
*/
|
|
506
|
+
file: string;
|
|
507
|
+
}
|
|
508
|
+
declare const ENCODING_MAPPING: {
|
|
509
|
+
zstd: string;
|
|
510
|
+
br: string;
|
|
511
|
+
gzip: string;
|
|
512
|
+
deflate: string;
|
|
513
|
+
identity: string;
|
|
514
|
+
};
|
|
515
|
+
type FileEncodingFormat = keyof typeof ENCODING_MAPPING;
|
|
516
|
+
declare const negotiateEncoding: (options: FileEncodingFormat[] | Record<FileEncodingFormat, string>) => FileNegotiation;
|
|
517
|
+
interface NegotiationOutputInfo {
|
|
518
|
+
mime?: string | undefined;
|
|
519
|
+
language?: string | undefined;
|
|
520
|
+
encoding?: string | undefined;
|
|
521
|
+
}
|
|
522
|
+
interface NegotiationOutput {
|
|
523
|
+
filename: string;
|
|
524
|
+
info: NegotiationOutputInfo;
|
|
525
|
+
}
|
|
526
|
+
type NegotiationInput = Partial<Record<NegotiationType, QualityValue[] | undefined>>;
|
|
527
|
+
interface Negotiator {
|
|
528
|
+
options(base: string, negotiation: NegotiationInput): Generator<NegotiationOutput, undefined, undefined>;
|
|
529
|
+
vary: string;
|
|
530
|
+
}
|
|
531
|
+
declare function makeNegotiator(rules: FileNegotiation[], maxFailedAttempts?: number): Negotiator;
|
|
532
|
+
|
|
533
|
+
interface FileFinderOptions {
|
|
534
|
+
/**
|
|
535
|
+
* Also serve files from sub-directories.
|
|
536
|
+
* Can be set to a number to control the depth of subdirectories served (where 0 means no
|
|
537
|
+
* subdirectories).
|
|
538
|
+
*
|
|
539
|
+
* @default true
|
|
540
|
+
*/
|
|
541
|
+
subDirectories?: boolean | number | undefined;
|
|
542
|
+
/**
|
|
543
|
+
* Configure case sensitivity of paths.
|
|
544
|
+
*
|
|
545
|
+
* `exact`: ensure that the path exactly matches the filesystem, even if the filesystem
|
|
546
|
+
* itself is case insensitive.
|
|
547
|
+
*
|
|
548
|
+
* `filesystem`: use the case sensitivity of the filesystem.
|
|
549
|
+
*
|
|
550
|
+
* `force-lowercase`: lowercase all requests before forwarding to the filesystem (this
|
|
551
|
+
* can achieve case insensitivity on otherwise case sensitive filesystems, but only if
|
|
552
|
+
* all files and folders are stored as lowercase).
|
|
553
|
+
*
|
|
554
|
+
* @default 'exact'
|
|
555
|
+
*/
|
|
556
|
+
caseSensitive?: 'exact' | 'filesystem' | 'force-lowercase' | undefined;
|
|
557
|
+
/**
|
|
558
|
+
* Allow serving dotfiles.
|
|
559
|
+
* If `true`, all dotfiles will be available (note this can be a security risk if you have
|
|
560
|
+
* sensitive hidden files or directories in the directory being served, such as `.git`).
|
|
561
|
+
* If you only need some dotfiles to be made available, you can use `permit` instead, which
|
|
562
|
+
* lets you allow specific file / directory names.
|
|
563
|
+
*
|
|
564
|
+
* @default false
|
|
565
|
+
*/
|
|
566
|
+
allowAllDotfiles?: boolean | undefined;
|
|
567
|
+
/**
|
|
568
|
+
* Allow serving files which begin or end with a tilde.
|
|
569
|
+
* These are commonly backup files (e.g. generated by vim when editing a file), and may or
|
|
570
|
+
* may not be a security risk to expose, depending on your setup.
|
|
571
|
+
* If `true`, all tilde files will be available.
|
|
572
|
+
* If you only need some tilde files to be made available, you can use `permit` instead, which
|
|
573
|
+
* lets you allow specific file / directory names.
|
|
574
|
+
*
|
|
575
|
+
* @default false
|
|
576
|
+
*/
|
|
577
|
+
allowAllTildefiles?: boolean | undefined;
|
|
578
|
+
/**
|
|
579
|
+
* Serve index files when requested directly (e.g. `/foo/index.htm`).
|
|
580
|
+
* By default, index files (listed in `indexFiles`) are only served if the directory is requested.
|
|
581
|
+
*
|
|
582
|
+
* @default false
|
|
583
|
+
*/
|
|
584
|
+
allowDirectIndexAccess?: boolean | undefined;
|
|
585
|
+
/**
|
|
586
|
+
* Hide arbitrary files from direct access. For example, when supporting content negotiation
|
|
587
|
+
* you may wish to block direct access to the "negotiated" variants of files such as `/\.gz$/`.
|
|
588
|
+
*
|
|
589
|
+
* Matches are performed on each path component. If any match, the file is hidden. Regular
|
|
590
|
+
* expressions are automatically made case insensitive if `caseSensitive` is `'filesystem'` or
|
|
591
|
+
* `'force-lowercase'`
|
|
592
|
+
*
|
|
593
|
+
* In cases where both match the same path component, `allow` overrides `hide`.
|
|
594
|
+
*
|
|
595
|
+
* @default []
|
|
596
|
+
*/
|
|
597
|
+
hide?: (string | RegExp)[] | undefined;
|
|
598
|
+
/**
|
|
599
|
+
* Allow access to specific files which would otherwise be blocked as a dotfile, tilde file, or
|
|
600
|
+
* hidden by `hide`.
|
|
601
|
+
*
|
|
602
|
+
* @default ['.well-known']
|
|
603
|
+
*/
|
|
604
|
+
allow?: string[] | undefined;
|
|
605
|
+
/**
|
|
606
|
+
* Files to look for if a directory is requested.
|
|
607
|
+
* Note that direct access to these files will be blocked unless `allowDirectIndexAccess` is `true`.
|
|
608
|
+
*
|
|
609
|
+
* If an empty list is provided, no index files will be served.
|
|
610
|
+
*
|
|
611
|
+
* @default ['index.htm', 'index.html']
|
|
612
|
+
*/
|
|
613
|
+
indexFiles?: string[] | undefined;
|
|
614
|
+
/**
|
|
615
|
+
* Content negotiation rules to apply to files.
|
|
616
|
+
*
|
|
617
|
+
* This can be used to respond to the `Accept`, `Accept-Language`, and `Accept-Encoding` headers.
|
|
618
|
+
*
|
|
619
|
+
* For example: on a server with `foo.txt`, `foo.txt.gz`, and a negotiation rule mapping
|
|
620
|
+
* `gzip` => `{name}.gz`:
|
|
621
|
+
* - users requesting `foo.txt` may get `foo.txt.gz` with `Content-Encoding: gzip` if their
|
|
622
|
+
* client supports gzip encoding
|
|
623
|
+
* - users requesting `foo.txt` may get `foo.txt` with no `Content-Encoding` if their client
|
|
624
|
+
* does not support gzip encoding
|
|
625
|
+
*
|
|
626
|
+
* Note that file access is checked *before* content negotiation, so you must still provide a
|
|
627
|
+
* base "un-negotiated" file for each file you wish to serve (which will also be used in cases
|
|
628
|
+
* where users do not send any `Accept-*` headers, and where no match is found)
|
|
629
|
+
*
|
|
630
|
+
* Multiple rules can match simultaneously, if a specific enough file exists (for example you might
|
|
631
|
+
* have `foo-en.txt.gz` for `Accept-Language: en` and `Accept-Encoding: gzip`).
|
|
632
|
+
*
|
|
633
|
+
* In the case of conflicting rules, earlier rules take priority (so `encoding` rules should
|
|
634
|
+
* typically be specified last)
|
|
635
|
+
*
|
|
636
|
+
* See the helper `negotiateEncoding` for a simple way to support pre-compressed files.
|
|
637
|
+
*
|
|
638
|
+
* @default []
|
|
639
|
+
*/
|
|
640
|
+
negotiation?: FileNegotiation[] | undefined;
|
|
641
|
+
}
|
|
642
|
+
interface FileFinderCore {
|
|
643
|
+
find(pathParts: string[], negotiation?: NegotiationInput): Promise<ResolvedFileInfo | null>;
|
|
644
|
+
readonly vary: string;
|
|
645
|
+
}
|
|
646
|
+
declare class FileFinder implements FileFinderCore {
|
|
647
|
+
readonly vary: string;
|
|
648
|
+
static build(absBasePath: string, options: FileFinderOptions): Promise<FileFinder>;
|
|
649
|
+
/**
|
|
650
|
+
* Find a file which matches the path.
|
|
651
|
+
*
|
|
652
|
+
* Note that the returned value contains an active `FileHandle`, which must be closed.
|
|
653
|
+
*
|
|
654
|
+
* @param pathParts the request path, split into separate components
|
|
655
|
+
* @param negotiation any client-sent negotiation options to apply
|
|
656
|
+
* @returns details about the resolved file (including an active `FileHandle`), or `null`
|
|
657
|
+
*/
|
|
658
|
+
find(pathParts: string[], negotiation?: NegotiationInput): Promise<ResolvedFileInfo | null>;
|
|
659
|
+
precompute(): Promise<FileFinderCore>;
|
|
660
|
+
}
|
|
661
|
+
interface ResolvedFileInfo extends NegotiationOutputInfo {
|
|
662
|
+
handle: FileHandle;
|
|
663
|
+
canonicalPath: string;
|
|
664
|
+
negotiatedPath: string;
|
|
665
|
+
stats: Stats;
|
|
666
|
+
}
|
|
667
|
+
|
|
668
|
+
interface SavedFile {
|
|
669
|
+
path: string;
|
|
670
|
+
size: number;
|
|
671
|
+
}
|
|
672
|
+
interface TempFileStorage {
|
|
673
|
+
dir: string;
|
|
674
|
+
nextFile: () => string;
|
|
675
|
+
save: (stream: Readable | ReadableStream, options?: {
|
|
676
|
+
mode?: number | undefined;
|
|
677
|
+
}) => Promise<SavedFile>;
|
|
678
|
+
}
|
|
679
|
+
declare const makeTempFileStorage: (req: IncomingMessage) => Promise<TempFileStorage>;
|
|
680
|
+
|
|
681
|
+
type ProxyHeader = 'forwarded' | 'x-forwarded-for' | 'x-forwarded-host' | 'x-forwarded-proto' | 'x-forwarded-protocol' | 'x-url-scheme' | 'via';
|
|
682
|
+
interface GetClientOptions {
|
|
683
|
+
/**
|
|
684
|
+
* The number of proxies to trust.
|
|
685
|
+
*
|
|
686
|
+
* Although `trustedProxyAddresses` makes it easier to guarantee security, specifying a count of
|
|
687
|
+
* proxies is useful in cases where the IP of proxies is not known or can change.
|
|
688
|
+
*
|
|
689
|
+
* This should be set to the number of proxies in the chain for your deployment: 0 when exposed
|
|
690
|
+
* directly to the internet, 1 when running behind a proxy, 2 when using a local reverse proxy as
|
|
691
|
+
* well as a load balancer, etc.
|
|
692
|
+
*
|
|
693
|
+
* Note: you must make sure there is no way to access your server without going through at least
|
|
694
|
+
* this many proxies, otherwise users will be able to spoof their client details, such as IP
|
|
695
|
+
* address, requested hostname, and connection protocol.
|
|
696
|
+
*
|
|
697
|
+
* @default 0 if trustedProxyAddresses is not set
|
|
698
|
+
* @default infinity if trustedProxyAddresses is set
|
|
699
|
+
*/
|
|
700
|
+
trustedProxyCount?: number;
|
|
701
|
+
/**
|
|
702
|
+
* The proxies to trust.
|
|
703
|
+
*
|
|
704
|
+
* For maximum security this can be an array of IPv4 or IPv6 addresses (or CIDR ranges) of
|
|
705
|
+
* trusted proxies. You can also specify alias names here, for cases where a proxy will be
|
|
706
|
+
* labelled by an alias by the next proxy in the chain.
|
|
707
|
+
*
|
|
708
|
+
* @default none (trust all proxies within trustedProxyCount hops)
|
|
709
|
+
*/
|
|
710
|
+
trustedProxyAddresses?: string[];
|
|
711
|
+
/**
|
|
712
|
+
* The headers which are set (or cleared) by your proxy, and can therefore be trusted.
|
|
713
|
+
*
|
|
714
|
+
* To use proxy data, you must explicitly configure these headers to match those set by your
|
|
715
|
+
* proxy. Do not list headers which are not modified by your proxy, as this will allow clients
|
|
716
|
+
* to spoof data.
|
|
717
|
+
*
|
|
718
|
+
* @default [] (no headers are trusted)
|
|
719
|
+
*/
|
|
720
|
+
trustedHeaders: ProxyHeader[];
|
|
721
|
+
}
|
|
722
|
+
declare function makeGetClient({ trustedProxyCount, trustedProxyAddresses, trustedHeaders, }: GetClientOptions): (req: IncomingMessage) => ProxyChain;
|
|
723
|
+
interface ProxyChain {
|
|
724
|
+
trusted: ProxyNode[];
|
|
725
|
+
untrusted: ProxyNode[];
|
|
726
|
+
outwardChain: ProxyNode[];
|
|
727
|
+
edge: ProxyNode;
|
|
728
|
+
}
|
|
729
|
+
interface ProxyNode {
|
|
730
|
+
client: Address | undefined;
|
|
731
|
+
server: Address | undefined;
|
|
732
|
+
host: string | undefined;
|
|
733
|
+
proto: string | undefined;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
type ProxyRequestHeaderAdapter = (request: IncomingMessage, headers: OutgoingHttpHeaders) => OutgoingHttpHeaders;
|
|
737
|
+
type ProxyResponseHeaderAdapter = (request: IncomingMessage, proxyResponse: IncomingMessage, headers: OutgoingHttpHeaders) => OutgoingHttpHeaders;
|
|
738
|
+
declare function removeForwarded(_: IncomingMessage, headers: IncomingHttpHeaders): OutgoingHttpHeaders;
|
|
739
|
+
declare function replaceForwarded(req: IncomingMessage, headers: IncomingHttpHeaders): OutgoingHttpHeaders;
|
|
740
|
+
declare const sanitiseAndAppendForwarded: (getClient: (req: IncomingMessage) => {
|
|
741
|
+
outwardChain: ProxyNode[];
|
|
742
|
+
trusted: ProxyNode[];
|
|
743
|
+
}, { onlyTrusted }?: {
|
|
744
|
+
onlyTrusted?: boolean | undefined;
|
|
745
|
+
}) => (req: IncomingMessage, headers: IncomingHttpHeaders) => OutgoingHttpHeaders;
|
|
746
|
+
declare function simpleAppendForwarded(req: IncomingMessage, headers: IncomingHttpHeaders): OutgoingHttpHeaders;
|
|
747
|
+
|
|
748
|
+
interface ProxyOptions extends AgentOptions {
|
|
749
|
+
agent?: Agent | Agent$1 | undefined;
|
|
750
|
+
/**
|
|
751
|
+
* A list of headers to remove from proxied requests (runs before `requestHeaders`).
|
|
752
|
+
*
|
|
753
|
+
* @default ['connection', 'expect', 'host', 'keep-alive', 'proxy-authorization', 'transfer-encoding', 'upgrade', 'via']
|
|
754
|
+
*/
|
|
755
|
+
blockRequestHeaders?: string[] | undefined;
|
|
756
|
+
/**
|
|
757
|
+
* A list of headers to remove from proxied responses (runs before `responseHeaders`).
|
|
758
|
+
*
|
|
759
|
+
* @default ['connection', 'keep-alive', 'transfer-encoding']
|
|
760
|
+
*/
|
|
761
|
+
blockResponseHeaders?: string[] | undefined;
|
|
762
|
+
/**
|
|
763
|
+
* Mutators for the proxied request headers. e.g. `sanitiseAndAppendForwarded`.
|
|
764
|
+
*/
|
|
765
|
+
requestHeaders?: ProxyRequestHeaderAdapter[] | undefined;
|
|
766
|
+
/**
|
|
767
|
+
* Mutators for the proxied response headers.
|
|
768
|
+
*/
|
|
769
|
+
responseHeaders?: ProxyResponseHeaderAdapter[] | undefined;
|
|
770
|
+
}
|
|
771
|
+
declare function proxy(forwardHost: string, { blockRequestHeaders, requestHeaders, blockResponseHeaders, responseHeaders, agent, keepAlive, maxSockets, ...options }?: ProxyOptions): RequestHandler<unknown>;
|
|
772
|
+
|
|
773
|
+
declare function registerCharset(charset: string, transformerFactory: (options: TextDecoderOptions) => TransformStream<Uint8Array, string>): void;
|
|
774
|
+
declare function registerUTF32(): void;
|
|
775
|
+
|
|
776
|
+
declare function resetMime(): void;
|
|
777
|
+
/**
|
|
778
|
+
* Reads mime types from an Apache .types file format.
|
|
779
|
+
* See https://svn.apache.org/repos/asf/httpd/httpd/trunk/docs/conf/mime.types for an example.
|
|
780
|
+
*/
|
|
781
|
+
declare function readMimeTypes(types: string): Map<string, string>;
|
|
782
|
+
declare function decompressMime(definitions: string): Map<string, string>;
|
|
783
|
+
declare function registerMime(definitions: Map<string, string>): void;
|
|
784
|
+
declare function getMime(ext: string, charset?: string): string;
|
|
785
|
+
|
|
786
|
+
declare function checkIfModified(req: IncomingMessage, res: ServerResponse, fileStats: Pick<Stats, 'mtimeMs' | 'size'>): boolean;
|
|
787
|
+
declare function checkIfRange(req: IncomingMessage, res: ServerResponse, fileStats: Pick<Stats, 'mtimeMs' | 'size'>): boolean;
|
|
788
|
+
declare function compareETag(res: ServerResponse, stats: Pick<Stats, 'mtimeMs' | 'size'>, etags: string[]): boolean;
|
|
789
|
+
|
|
790
|
+
interface GetBodyOptions {
|
|
791
|
+
maxExpandedLength?: number;
|
|
792
|
+
maxContentLength?: number;
|
|
793
|
+
maxEncodingSteps?: number;
|
|
794
|
+
}
|
|
795
|
+
interface GetBodyTextOptions extends GetBodyOptions, TextDecoderOptions {
|
|
796
|
+
defaultCharset?: string;
|
|
797
|
+
}
|
|
798
|
+
interface GetBodyJsonOptions extends GetBodyOptions, TextDecoderOptions {
|
|
799
|
+
}
|
|
800
|
+
declare function getBodyStream(req: IncomingMessage, { maxExpandedLength, maxContentLength, maxEncodingSteps, }?: GetBodyOptions): ReadableStream<Uint8Array>;
|
|
801
|
+
declare function getBodyTextStream(req: IncomingMessage, options?: GetBodyTextOptions): ReadableStream<string>;
|
|
802
|
+
declare function getBodyText(req: IncomingMessage, options?: GetBodyTextOptions): Promise<string>;
|
|
803
|
+
declare function getBodyJson(req: IncomingMessage, options?: GetBodyJsonOptions): Promise<unknown>;
|
|
804
|
+
|
|
805
|
+
declare function acceptBody(req: IncomingMessage): void;
|
|
806
|
+
|
|
807
|
+
declare function getFormFields(req: IncomingMessage, { allowMultipart, closeAfterErrorDelay, limits }?: GetFormFieldsConfig): AsyncIterable<FormField, unknown, undefined>;
|
|
808
|
+
declare function getFormData(req: IncomingMessage, config?: GetFormDataConfig): Promise<AugmentedFormData>;
|
|
809
|
+
interface GetFormFieldsConfig {
|
|
810
|
+
allowMultipart?: boolean;
|
|
811
|
+
closeAfterErrorDelay?: number;
|
|
812
|
+
limits?: Limits;
|
|
813
|
+
}
|
|
814
|
+
interface GetFormDataConfig extends GetFormFieldsConfig {
|
|
815
|
+
/** true to apply .trim() to all field values */
|
|
816
|
+
trimAllValues?: boolean;
|
|
817
|
+
/** function to apply to all uploaded files (e.g. to check available disk space) */
|
|
818
|
+
preCheckFile?: PreCheckFile;
|
|
819
|
+
}
|
|
820
|
+
type PreCheckFile = (info: PreCheckFileInfo) => MaybePromise<PostCheckFile | void>;
|
|
821
|
+
interface PreCheckFileInfo {
|
|
822
|
+
fieldName: string;
|
|
823
|
+
filename: string;
|
|
824
|
+
encoding: string;
|
|
825
|
+
mimeType: string;
|
|
826
|
+
maxBytes: number | undefined;
|
|
827
|
+
}
|
|
828
|
+
type PostCheckFile = (actual: PostCheckFileInfo) => MaybePromise<void>;
|
|
829
|
+
interface PostCheckFileInfo {
|
|
830
|
+
actualBytes: number;
|
|
831
|
+
}
|
|
832
|
+
type FormField = {
|
|
833
|
+
name: string;
|
|
834
|
+
mimeType: string;
|
|
835
|
+
encoding: string;
|
|
836
|
+
} & ({
|
|
837
|
+
type: 'string';
|
|
838
|
+
value: string;
|
|
839
|
+
} | {
|
|
840
|
+
type: 'file';
|
|
841
|
+
value: Readable;
|
|
842
|
+
filename: string;
|
|
843
|
+
});
|
|
844
|
+
interface AugmentedFormData extends FormData {
|
|
845
|
+
getTempFilePath(file: Blob): string;
|
|
846
|
+
getBoolean(name: string): boolean | null;
|
|
847
|
+
}
|
|
848
|
+
interface Limits {
|
|
849
|
+
/**
|
|
850
|
+
* Max field name size (in bytes).
|
|
851
|
+
*
|
|
852
|
+
* @default 100
|
|
853
|
+
*/
|
|
854
|
+
fieldNameSize?: number | undefined;
|
|
855
|
+
/**
|
|
856
|
+
* Max field value size (in bytes).
|
|
857
|
+
*
|
|
858
|
+
* @default 1048576 (1MB)
|
|
859
|
+
*/
|
|
860
|
+
fieldSize?: number | undefined;
|
|
861
|
+
/**
|
|
862
|
+
* Max number of non-file fields.
|
|
863
|
+
*
|
|
864
|
+
* @default Infinity
|
|
865
|
+
*/
|
|
866
|
+
fields?: number | undefined;
|
|
867
|
+
/**
|
|
868
|
+
* For multipart forms, the max file size (in bytes).
|
|
869
|
+
*
|
|
870
|
+
* @default Infinity
|
|
871
|
+
*/
|
|
872
|
+
fileSize?: number | undefined;
|
|
873
|
+
/**
|
|
874
|
+
* For multipart forms, the max number of file fields.
|
|
875
|
+
*
|
|
876
|
+
* @default Infinity
|
|
877
|
+
*/
|
|
878
|
+
files?: number | undefined;
|
|
879
|
+
/**
|
|
880
|
+
* For multipart forms, the max number of parts (fields + files).
|
|
881
|
+
*
|
|
882
|
+
* @default Infinity
|
|
883
|
+
*/
|
|
884
|
+
parts?: number | undefined;
|
|
885
|
+
/**
|
|
886
|
+
* For multipart forms, the max number of header key-value pairs to parse.
|
|
887
|
+
*
|
|
888
|
+
* @default 2000 (same as node's http module)
|
|
889
|
+
*/
|
|
890
|
+
headerPairs?: number | undefined;
|
|
891
|
+
}
|
|
892
|
+
|
|
893
|
+
declare function getRemainingPathComponents(req: IncomingMessage, { rejectPotentiallyUnsafe }?: {
|
|
894
|
+
rejectPotentiallyUnsafe?: boolean | undefined;
|
|
895
|
+
}): string[];
|
|
896
|
+
|
|
897
|
+
interface CSVOptions {
|
|
898
|
+
/**
|
|
899
|
+
* The delimiter to use between cells
|
|
900
|
+
* @default ','
|
|
901
|
+
*/
|
|
902
|
+
delimiter?: string | Uint8Array;
|
|
903
|
+
/**
|
|
904
|
+
* The delimiter to use between rows
|
|
905
|
+
* @default '\n'
|
|
906
|
+
*/
|
|
907
|
+
newline?: string | Uint8Array;
|
|
908
|
+
/**
|
|
909
|
+
* The quote character to use. Typically should be `"` or (if the target application supports it) `'`
|
|
910
|
+
* @default '"'
|
|
911
|
+
*/
|
|
912
|
+
quote?: string;
|
|
913
|
+
/**
|
|
914
|
+
* The text encoding to use.
|
|
915
|
+
* @default 'utf-8'
|
|
916
|
+
*/
|
|
917
|
+
encoding?: BufferEncoding;
|
|
918
|
+
/**
|
|
919
|
+
* For use with `ServerResponse` targets.
|
|
920
|
+
* If `true`, adds header=present to the mime type; if `false`, adds header=absent to the mime type.
|
|
921
|
+
* @default undefined
|
|
922
|
+
*/
|
|
923
|
+
headerRow?: boolean | undefined;
|
|
924
|
+
/**
|
|
925
|
+
* If `true`, will call `end()` on target stream after writing.
|
|
926
|
+
* @default true
|
|
927
|
+
*/
|
|
928
|
+
end?: boolean;
|
|
929
|
+
}
|
|
930
|
+
type MaybeAsyncIterable<T> = Iterable<T> | AsyncIterable<T>;
|
|
931
|
+
/**
|
|
932
|
+
* Output a CSV formatted table, using the format from RFC4180.
|
|
933
|
+
* Specifically:
|
|
934
|
+
* - lines are separated by newlines;
|
|
935
|
+
* - cells are separated by commas;
|
|
936
|
+
* - cells containing whitespace, commas, newlines, etc. are quoted with double quotes;
|
|
937
|
+
* - double quotes appearing inside cell values are escaped by doubling: `"a""b"`.
|
|
938
|
+
*
|
|
939
|
+
* The line and cell delimiters can be configured (e.g. `{ delimiter: '\t', newline: '\r\n' }`)
|
|
940
|
+
*/
|
|
941
|
+
declare function sendCSVStream(target: Writable, table: MaybeAsyncIterable<MaybeAsyncIterable<string | null | undefined>>, { delimiter, newline, quote, encoding, headerRow, end, }?: CSVOptions): Promise<void>;
|
|
942
|
+
|
|
943
|
+
declare function sendFile(req: IncomingMessage, res: ServerResponse, file: string | FileHandle | Readable | ReadableStream<Uint8Array>, fileStats: Pick<Stats, 'mtimeMs' | 'size'> | null, options?: GetRangeOptions & SimplifyRangeOptions): Promise<void>;
|
|
944
|
+
|
|
945
|
+
interface JSONOptions {
|
|
946
|
+
replacer?: ((this: unknown, key: string, value: unknown) => unknown) | (number | string)[] | null;
|
|
947
|
+
space?: string | number;
|
|
948
|
+
undefinedAsNull?: boolean;
|
|
949
|
+
encoding?: BufferEncoding;
|
|
950
|
+
end?: boolean;
|
|
951
|
+
}
|
|
952
|
+
declare function sendJSON(target: Writable, entity: unknown, { replacer, space, undefinedAsNull, encoding, end }?: JSONOptions): void;
|
|
953
|
+
declare function sendJSONStream(target: Writable, entity: unknown, { replacer, space, undefinedAsNull, encoding, end, }?: JSONOptions): Promise<void>;
|
|
954
|
+
|
|
955
|
+
declare function sendRanges(req: IncomingMessage, res: ServerResponse, file: string | FileHandle | Readable | ReadableStream<Uint8Array>, httpRange: HTTPRange): Promise<void>;
|
|
956
|
+
|
|
957
|
+
interface ServerSentEventsOptions {
|
|
958
|
+
keepaliveInterval?: number;
|
|
959
|
+
softCloseReconnectDelay?: number;
|
|
960
|
+
softCloseReconnectStagger?: number;
|
|
961
|
+
}
|
|
962
|
+
interface ServerSentEvent {
|
|
963
|
+
event?: string;
|
|
964
|
+
data?: string;
|
|
965
|
+
id?: string;
|
|
966
|
+
reconnectDelay?: number;
|
|
967
|
+
}
|
|
968
|
+
declare class ServerSentEvents {
|
|
969
|
+
constructor(req: IncomingMessage, res: ServerResponse, { keepaliveInterval, softCloseReconnectDelay, softCloseReconnectStagger, }?: ServerSentEventsOptions);
|
|
970
|
+
get signal(): AbortSignal;
|
|
971
|
+
get open(): boolean;
|
|
972
|
+
ping(): void;
|
|
973
|
+
send({ event, id, data, reconnectDelay }: ServerSentEvent): Promise<void>;
|
|
974
|
+
sendFields(parts: [string, string | undefined][]): Promise<void>;
|
|
975
|
+
close(reconnectDelay?: number, reconnectStagger?: number): Promise<void>;
|
|
976
|
+
}
|
|
977
|
+
|
|
978
|
+
interface FileServerOptions extends FileFinderOptions {
|
|
979
|
+
/**
|
|
980
|
+
* The mode of serving files to use.
|
|
981
|
+
*
|
|
982
|
+
* 'dynamic' checks the filesystem for each request.
|
|
983
|
+
* This is a good choice for local development, and for production in cases where files in a
|
|
984
|
+
* directory are able to change at runtime (e.g. uploaded content).
|
|
985
|
+
*
|
|
986
|
+
* 'static-paths' scans the directory at startup then uses an in-memory reference to check
|
|
987
|
+
* requested paths.
|
|
988
|
+
* This can improve performance and increase security, as long as the list of avalable files
|
|
989
|
+
* will not change at runtime. The contents of the files are still loaded for each request.
|
|
990
|
+
* This is usually a good choice for production deployments.
|
|
991
|
+
*
|
|
992
|
+
* @default 'dynamic'
|
|
993
|
+
*/
|
|
994
|
+
mode?: 'dynamic' | 'static-paths' | undefined;
|
|
995
|
+
/**
|
|
996
|
+
* Serve a file if the requested path is not found.
|
|
997
|
+
* By default, the handler will return `CONTINUE`, but by providing this option you can
|
|
998
|
+
* automatically return a particular file as fallback content (e.g. for Single-Page-Apps).
|
|
999
|
+
*
|
|
1000
|
+
* Compression, cache control, and range requests will continue to work as usual.
|
|
1001
|
+
*/
|
|
1002
|
+
fallback?: FallbackOptions | undefined;
|
|
1003
|
+
/**
|
|
1004
|
+
* A function to call when a file is being served. Can modify headers in the response.
|
|
1005
|
+
* The default implementation is:
|
|
1006
|
+
*
|
|
1007
|
+
* ```
|
|
1008
|
+
* res.setHeader('etag', generateWeakETag(res.getHeader('content-encoding'), file.stats));
|
|
1009
|
+
* res.setHeader('last-modified', file.stats.mtime.toUTCString());
|
|
1010
|
+
* ```
|
|
1011
|
+
*
|
|
1012
|
+
* If you override this function, you must decide which cache headers you wish to set.
|
|
1013
|
+
*
|
|
1014
|
+
* This function is called after the `Content-Type` and `Content-Encoding` headers have been set,
|
|
1015
|
+
* so you can inspect those if you need to know the mime type or encoding of the response, or
|
|
1016
|
+
* change them if you want to set different values.
|
|
1017
|
+
*
|
|
1018
|
+
* @param req
|
|
1019
|
+
* @param res
|
|
1020
|
+
* @param file information about the file, including `fs.Stats` and an active `FileHandle`
|
|
1021
|
+
* @param isFallback `true` if the file is being served as a fallback (e.g. error page or Single-Page-App)
|
|
1022
|
+
*/
|
|
1023
|
+
callback?: ((req: IncomingMessage, res: ServerResponse, file: ResolvedFileInfo, isFallback: boolean) => MaybePromise<void>) | undefined;
|
|
1024
|
+
}
|
|
1025
|
+
interface FallbackOptions {
|
|
1026
|
+
/**
|
|
1027
|
+
* The status code to return with the fallback content.
|
|
1028
|
+
*
|
|
1029
|
+
* @default 200 (OK)
|
|
1030
|
+
*/
|
|
1031
|
+
statusCode?: number | undefined;
|
|
1032
|
+
/**
|
|
1033
|
+
* The path of the fallback content to use.
|
|
1034
|
+
*/
|
|
1035
|
+
filePath: string;
|
|
1036
|
+
}
|
|
1037
|
+
/**
|
|
1038
|
+
* Set up a server for static files in a directory. The options are secure by default.
|
|
1039
|
+
* Requests for files which are not permitted or do not exist will return NEXT_ROUTE and can be
|
|
1040
|
+
* handled by subsequent routes.
|
|
1041
|
+
*
|
|
1042
|
+
* @param basePath the path to the directory to serve (relative paths are to the current working directory)
|
|
1043
|
+
* @param options custom configuration to apply
|
|
1044
|
+
* @returns a promise of a server handler function (note this should be `await`ed before being used as a handler!)
|
|
1045
|
+
*/
|
|
1046
|
+
declare const fileServer: (basePath: string, { mode, fallback, callback, ...options }?: FileServerOptions) => Promise<RequestHandler>;
|
|
1047
|
+
declare function setDefaultCacheHeaders(req: IncomingMessage, res: ServerResponse, file: ResolvedFileInfo): void;
|
|
1048
|
+
|
|
1049
|
+
interface InternalWebSocketServerOptions {
|
|
1050
|
+
noServer?: true;
|
|
1051
|
+
clientTracking?: false;
|
|
1052
|
+
WebSocket?: any;
|
|
1053
|
+
}
|
|
1054
|
+
type ForbiddenWebSocketServerOptions = 'backlog' | 'server' | 'noServer' | 'clientTracking' | 'host' | 'port' | 'path' | 'verifyClient';
|
|
1055
|
+
declare class WebSocketServer<T, Options> {
|
|
1056
|
+
constructor(options: Options);
|
|
1057
|
+
handleUpgrade(req: IncomingMessage, socket: Duplex, head: Buffer, callback: (ws: T) => void): void;
|
|
1058
|
+
once(event: 'wsClientError', handler: (error: Error) => void): void;
|
|
1059
|
+
off(event: 'wsClientError', handler: (error: Error) => void): void;
|
|
1060
|
+
}
|
|
1061
|
+
interface ClosableWebSocket {
|
|
1062
|
+
close(status: number, message?: string): void;
|
|
1063
|
+
}
|
|
1064
|
+
interface WebSocketOptions {
|
|
1065
|
+
softCloseStatusCode?: number | undefined;
|
|
1066
|
+
}
|
|
1067
|
+
declare function makeAcceptWebSocket<T extends ClosableWebSocket, PassThroughOptions>(wsServerClass: typeof WebSocketServer<T, InternalWebSocketServerOptions & PassThroughOptions>, { softCloseStatusCode, ...options }?: Partial<PassThroughOptions & Record<ForbiddenWebSocketServerOptions, never>> & {
|
|
1068
|
+
WebSocket?: (new (...args: any) => T) | undefined;
|
|
1069
|
+
} & WebSocketOptions): (req: IncomingMessage) => Promise<T>;
|
|
1070
|
+
|
|
1071
|
+
type MessageHandler = ((data: string | Buffer) => void) & ((data: Buffer, isBinary: boolean) => void);
|
|
1072
|
+
type CloseHandler = () => void;
|
|
1073
|
+
interface ListenableWebSocket {
|
|
1074
|
+
on(event: 'message', handler: MessageHandler): void;
|
|
1075
|
+
on(event: 'close', handler: CloseHandler): void;
|
|
1076
|
+
off(event: 'message', handler: MessageHandler): void;
|
|
1077
|
+
off(event: 'close', handler: CloseHandler): void;
|
|
1078
|
+
readyState?: number;
|
|
1079
|
+
}
|
|
1080
|
+
declare class WebSocketMessage {
|
|
1081
|
+
readonly data: Buffer;
|
|
1082
|
+
readonly isBinary: boolean;
|
|
1083
|
+
constructor(data: Buffer, isBinary: boolean);
|
|
1084
|
+
get text(): string;
|
|
1085
|
+
get binary(): Buffer<ArrayBufferLike>;
|
|
1086
|
+
}
|
|
1087
|
+
interface WebSocketMessagesOptions {
|
|
1088
|
+
limit?: number;
|
|
1089
|
+
signal?: AbortSignal | undefined;
|
|
1090
|
+
}
|
|
1091
|
+
declare class WebSocketMessages implements AsyncIterable<WebSocketMessage, unknown, undefined> {
|
|
1092
|
+
readonly detach: () => void;
|
|
1093
|
+
constructor(ws: ListenableWebSocket, { limit, signal }?: WebSocketMessagesOptions);
|
|
1094
|
+
next(timeout?: number): Promise<WebSocketMessage>;
|
|
1095
|
+
[Symbol.asyncIterator](): AsyncIterator<WebSocketMessage, unknown, undefined>;
|
|
1096
|
+
}
|
|
1097
|
+
declare function nextWebSocketMessage(ws: ListenableWebSocket, { timeout, signal }?: {
|
|
1098
|
+
timeout?: number;
|
|
1099
|
+
signal?: AbortSignal;
|
|
1100
|
+
}): Promise<WebSocketMessage>;
|
|
1101
|
+
|
|
1102
|
+
declare function isWebSocketRequest(req: IncomingMessage): boolean;
|
|
1103
|
+
declare const getWebSocketOrigin: (req: IncomingMessage) => string | undefined;
|
|
1104
|
+
/**
|
|
1105
|
+
* Factory for a fallback authentication token fetcher for websockets. Browsers do not allow setting the
|
|
1106
|
+
* Authorization header when creating a websocket, so this allows the token to be sent as the first message
|
|
1107
|
+
* instead.
|
|
1108
|
+
*
|
|
1109
|
+
* @param acceptWebSocket a function for accepting a websocket (e.g. `makeAcceptWebSocket(WebSocketServer)`)
|
|
1110
|
+
* @returns a function suitable for use with `requireBearerAuth`'s `fallbackTokenFetcher` option.
|
|
1111
|
+
*/
|
|
1112
|
+
declare const makeWebSocketFallbackTokenFetcher: <Req>(acceptWebSocket: (req: IncomingMessage & Req) => Promise<ListenableWebSocket>, timeout?: number) => (req: IncomingMessage & Req) => Promise<string | undefined>;
|
|
1113
|
+
|
|
1114
|
+
interface WebSocketErrorOptions {
|
|
1115
|
+
message?: string;
|
|
1116
|
+
statusMessage?: string;
|
|
1117
|
+
cause?: unknown;
|
|
1118
|
+
}
|
|
1119
|
+
declare class WebSocketError extends Error {
|
|
1120
|
+
readonly statusCode: number;
|
|
1121
|
+
readonly statusMessage: string;
|
|
1122
|
+
constructor(statusCode: number, { message, statusMessage, ...options }?: WebSocketErrorOptions);
|
|
1123
|
+
static readonly NORMAL_CLOSURE = 1000;
|
|
1124
|
+
static readonly GOING_AWAY = 1001;
|
|
1125
|
+
static readonly UNSUPPORTED_DATA = 1003;
|
|
1126
|
+
static readonly POLICY_VIOLATION = 1008;
|
|
1127
|
+
static readonly MESSAGE_TOO_BIG = 1009;
|
|
1128
|
+
static readonly INTERNAL_SERVER_ERROR = 1011;
|
|
1129
|
+
static readonly SERVICE_RESTART = 1012;
|
|
1130
|
+
static readonly TRY_AGAIN_LATER = 1013;
|
|
1131
|
+
static readonly BAD_GATEWAY = 1014;
|
|
1132
|
+
}
|
|
1133
|
+
|
|
1134
|
+
interface Property<T> {
|
|
1135
|
+
factory: (req: IncomingMessage) => T;
|
|
1136
|
+
set(req: IncomingMessage, value: T): void;
|
|
1137
|
+
get(req: IncomingMessage): T;
|
|
1138
|
+
clear(req: IncomingMessage): void;
|
|
1139
|
+
}
|
|
1140
|
+
declare function makeProperty<T>(defaultValue: T | ((req: IncomingMessage) => T)): Property<T>;
|
|
1141
|
+
declare const makeMemo: <T, Args extends any[] = []>(fn: (req: IncomingMessage, ...args: Args) => T, ...args: Args) => ((req: IncomingMessage) => T);
|
|
1142
|
+
declare function setProperty<T>(req: IncomingMessage, property: Property<T>, value: T): void;
|
|
1143
|
+
declare function getProperty<T>(req: IncomingMessage, property: Property<T>): T;
|
|
1144
|
+
declare function clearProperty<T>(req: IncomingMessage, property: Property<T>): void;
|
|
1145
|
+
|
|
1146
|
+
export { BlockingQueue, CONTINUE, FileFinder, HTTPError, NEXT_ROUTE, NEXT_ROUTER, Queue, Router, STOP, ServerSentEvents, WebListener, WebSocketError, WebSocketMessage, WebSocketMessages, acceptBody, acceptUpgrade, addTeardown, anyHandler, checkIfModified, checkIfRange, clearProperty, compareETag, decompressMime, defer, errorHandler, fileServer, findCause, generateStrongETag, generateWeakETag, getAbortSignal, getAbsolutePath, getAddressURL, getAuthData, getAuthorization, getBodyJson, getBodyStream, getBodyText, getBodyTextStream, getCharset, getFormData, getFormFields, getIfRange, getMime, getPathParameter, getPathParameters, getProperty, getQuery, getRange, getRemainingPathComponents, getSearch, getSearchParams, getWebSocketOrigin, hasAuthScope, isSoftClosed, isWebSocketRequest, makeAcceptWebSocket, makeAddressTester, makeGetClient, makeMemo, makeNegotiator, makeProperty, makeTempFileStorage, makeWebSocketFallbackTokenFetcher, negotiateEncoding, nextWebSocketMessage, parseAddress, proxy, readHTTPDateSeconds, readHTTPInteger, readHTTPKeyValues, readHTTPQualityValues, readHTTPUnquotedCommaSeparated, readMimeTypes, registerCharset, registerMime, registerUTF32, removeForwarded, replaceForwarded, requestHandler, requireAuthScope, requireBearerAuth, resetMime, restoreAbsolutePath, sanitiseAndAppendForwarded, sendCSVStream, sendFile, sendJSON, sendJSONStream, sendRanges, setDefaultCacheHeaders, setProperty, setSoftCloseHandler, simpleAppendForwarded, simplifyRange, toListeners, upgradeHandler };
|
|
1147
|
+
export type { AcceptUpgradeHandler, AcceptUpgradeResult, Address, AugmentedFormData, CSVOptions, CombinedServerOptions, CommonMethod, CommonUpgrade, ErrorHandler, FileFinderCore, FileFinderOptions, FileNegotiation, FileNegotiationOption, FileServerOptions, FormField, GetClientOptions, GetFormDataConfig, GetFormFieldsConfig, GetRangeOptions, HTTPErrorOptions, HTTPRange, HandlerResult, JSONOptions, ListenOptions, ListenerOptions, NativeListeners, NegotiationInput, NegotiationOutput, NegotiationOutputInfo, Negotiator, ParametersFromPath, PostCheckFile, PostCheckFileInfo, PreCheckFile, PreCheckFileInfo, Property, ProxyChain, ProxyNode, ProxyOptions, ProxyRequestHeaderAdapter, ProxyResponseHeaderAdapter, QualityValue, RangePart, RequestHandler, ResolvedFileInfo, ServerErrorCallback, ServerGeneralErrorCallback, ServerSentEvent, SimplifyRangeOptions, UpgradeHandler, UpgradeListener, WithPathParameters, WithoutPathParameters };
|