server.d.ts 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272
  1. import { EventEmitter } from "events";
  2. import { Socket } from "./socket";
  3. import { type PerMessageDeflateOptions } from "ws";
  4. import type { IncomingMessage, Server as HttpServer, ServerResponse } from "http";
  5. import type { CorsOptions, CorsOptionsDelegate } from "cors";
  6. import type { Duplex } from "stream";
  7. import type { EngineRequest, Transport } from "./transport";
  8. import type { CookieSerializeOptions } from "./contrib/types.cookie";
  9. type TransportName = "polling" | "websocket" | "webtransport";
  10. export type ErrorCallback = (errorCode?: (typeof Server.errors)[keyof typeof Server.errors], errorContext?: Record<string, unknown> & {
  11. name?: string;
  12. message?: string;
  13. }) => void;
  14. export interface AttachOptions {
  15. /**
  16. * name of the path to capture
  17. * @default "/engine.io"
  18. */
  19. path?: string;
  20. /**
  21. * destroy unhandled upgrade requests
  22. * @default true
  23. */
  24. destroyUpgrade?: boolean;
  25. /**
  26. * milliseconds after which unhandled requests are ended
  27. * @default 1000
  28. */
  29. destroyUpgradeTimeout?: number;
  30. /**
  31. * Whether we should add a trailing slash to the request path.
  32. * @default true
  33. */
  34. addTrailingSlash?: boolean;
  35. }
  36. export interface ServerOptions {
  37. /**
  38. * how many ms without a pong packet to consider the connection closed
  39. * @default 20000
  40. */
  41. pingTimeout?: number;
  42. /**
  43. * how many ms before sending a new ping packet
  44. * @default 25000
  45. */
  46. pingInterval?: number;
  47. /**
  48. * how many ms before an uncompleted transport upgrade is cancelled
  49. * @default 10000
  50. */
  51. upgradeTimeout?: number;
  52. /**
  53. * how many bytes or characters a message can be, before closing the session (to avoid DoS).
  54. * @default 1e5 (100 KB)
  55. */
  56. maxHttpBufferSize?: number;
  57. /**
  58. * A function that receives a given handshake or upgrade request as its first parameter,
  59. * and can decide whether to continue or not. The second argument is a function that needs
  60. * to be called with the decided information: fn(err, success), where success is a boolean
  61. * value where false means that the request is rejected, and err is an error code.
  62. */
  63. allowRequest?: (req: IncomingMessage, fn: (err: string | null | undefined, success: boolean) => void) => void;
  64. /**
  65. * The low-level transports that are enabled. WebTransport is disabled by default and must be manually enabled:
  66. *
  67. * @example
  68. * new Server({
  69. * transports: ["polling", "websocket", "webtransport"]
  70. * });
  71. *
  72. * @default ["polling", "websocket"]
  73. */
  74. transports?: TransportName[];
  75. /**
  76. * whether to allow transport upgrades
  77. * @default true
  78. */
  79. allowUpgrades?: boolean;
  80. /**
  81. * parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to false to disable.
  82. * @default false
  83. */
  84. perMessageDeflate?: boolean | PerMessageDeflateOptions;
  85. /**
  86. * parameters of the http compression for the polling transports (see zlib api docs). Set to false to disable.
  87. * @default true
  88. */
  89. httpCompression?: boolean | object;
  90. /**
  91. * what WebSocket server implementation to use. Specified module must
  92. * conform to the ws interface (see ws module api docs).
  93. * An alternative c++ addon is also available by installing eiows module.
  94. *
  95. * @default `require("ws").Server`
  96. */
  97. wsEngine?: any;
  98. /**
  99. * an optional packet which will be concatenated to the handshake packet emitted by Engine.IO.
  100. */
  101. initialPacket?: any;
  102. /**
  103. * configuration of the cookie that contains the client sid to send as part of handshake response headers. This cookie
  104. * might be used for sticky-session. Defaults to not sending any cookie.
  105. * @default false
  106. */
  107. cookie?: (CookieSerializeOptions & {
  108. name: string;
  109. }) | boolean;
  110. /**
  111. * the options that will be forwarded to the cors module
  112. */
  113. cors?: CorsOptions | CorsOptionsDelegate;
  114. /**
  115. * whether to enable compatibility with Socket.IO v2 clients
  116. * @default false
  117. */
  118. allowEIO3?: boolean;
  119. }
  120. /**
  121. * An Express-compatible middleware.
  122. *
  123. * Middleware functions are functions that have access to the request object (req), the response object (res), and the
  124. * next middleware function in the application’s request-response cycle.
  125. *
  126. * @see https://expressjs.com/en/guide/using-middleware.html
  127. */
  128. type Middleware = (req: IncomingMessage, res: ServerResponse, next: (err?: any) => void) => void;
  129. export declare abstract class BaseServer extends EventEmitter {
  130. opts: ServerOptions;
  131. protected clients: Record<string, Socket>;
  132. clientsCount: number;
  133. protected middlewares: Middleware[];
  134. /**
  135. * Server constructor.
  136. *
  137. * @param {Object} opts - options
  138. */
  139. constructor(opts?: ServerOptions);
  140. protected abstract init(): void;
  141. /**
  142. * Compute the pathname of the requests that are handled by the server
  143. * @param options
  144. * @protected
  145. */
  146. protected _computePath(options: AttachOptions): string;
  147. /**
  148. * Returns a list of available transports for upgrade given a certain transport.
  149. */
  150. upgrades(transport: TransportName): string[];
  151. /**
  152. * Verifies a request.
  153. *
  154. * @param {EngineRequest} req
  155. * @param upgrade - whether it's an upgrade request
  156. * @param fn
  157. * @protected
  158. * @return whether the request is valid
  159. */
  160. protected verify(req: EngineRequest, upgrade: boolean, fn: ErrorCallback): void | boolean;
  161. /**
  162. * Adds a new middleware.
  163. *
  164. * @example
  165. * import helmet from "helmet";
  166. *
  167. * engine.use(helmet());
  168. *
  169. * @param fn
  170. */
  171. use(fn: any): void;
  172. /**
  173. * Apply the middlewares to the request.
  174. *
  175. * @param req
  176. * @param res
  177. * @param callback
  178. * @protected
  179. */
  180. protected _applyMiddlewares(req: IncomingMessage, res: ServerResponse, callback: (err?: any) => void): void;
  181. /**
  182. * Closes all clients.
  183. */
  184. close(): this;
  185. protected abstract cleanup(): any;
  186. /**
  187. * generate a socket id.
  188. * Overwrite this method to generate your custom socket id
  189. *
  190. * @param {IncomingMessage} req - the request object
  191. */
  192. generateId(req: IncomingMessage): string | PromiseLike<string>;
  193. /**
  194. * Handshakes a new client.
  195. *
  196. * @param {String} transportName
  197. * @param {Object} req - the request object
  198. * @param {Function} closeConnection
  199. *
  200. * @protected
  201. */
  202. protected handshake(transportName: TransportName, req: EngineRequest, closeConnection: ErrorCallback): Promise<any>;
  203. onWebTransportSession(session: any): Promise<any>;
  204. protected abstract createTransport(transportName: TransportName, req: EngineRequest): any;
  205. /**
  206. * Protocol errors mappings.
  207. */
  208. static errors: {
  209. readonly UNKNOWN_TRANSPORT: 0;
  210. readonly UNKNOWN_SID: 1;
  211. readonly BAD_HANDSHAKE_METHOD: 2;
  212. readonly BAD_REQUEST: 3;
  213. readonly FORBIDDEN: 4;
  214. readonly UNSUPPORTED_PROTOCOL_VERSION: 5;
  215. };
  216. static errorMessages: {
  217. readonly 0: "Transport unknown";
  218. readonly 1: "Session ID unknown";
  219. readonly 2: "Bad handshake method";
  220. readonly 3: "Bad request";
  221. readonly 4: "Forbidden";
  222. readonly 5: "Unsupported protocol version";
  223. };
  224. }
  225. /**
  226. * An Engine.IO server based on Node.js built-in HTTP server and the `ws` package for WebSocket connections.
  227. */
  228. export declare class Server extends BaseServer {
  229. httpServer?: HttpServer;
  230. private ws;
  231. /**
  232. * Initialize websocket server
  233. *
  234. * @protected
  235. */
  236. protected init(): void;
  237. protected cleanup(): void;
  238. /**
  239. * Prepares a request by processing the query string.
  240. *
  241. * @private
  242. */
  243. private prepare;
  244. protected createTransport(transportName: TransportName, req: IncomingMessage): Transport;
  245. /**
  246. * Handles an Engine.IO HTTP request.
  247. *
  248. * @param {EngineRequest} req
  249. * @param {ServerResponse} res
  250. */
  251. handleRequest(req: EngineRequest, res: ServerResponse): void;
  252. /**
  253. * Handles an Engine.IO HTTP Upgrade.
  254. */
  255. handleUpgrade(req: EngineRequest, socket: Duplex, upgradeHead: Buffer): void;
  256. /**
  257. * Called upon a ws.io connection.
  258. * @param req
  259. * @param socket
  260. * @param websocket
  261. * @private
  262. */
  263. private onWebSocket;
  264. /**
  265. * Captures upgrade requests for a http.Server.
  266. *
  267. * @param {http.Server} server
  268. * @param {Object} options
  269. */
  270. attach(server: HttpServer, options?: AttachOptions): void;
  271. }
  272. export {};