mirror of
https://github.com/socketio/socket.io.git
synced 2026-01-09 15:08:12 -05:00
refactor: improve type annotations and comments (#5364)
This commit is contained in:
committed by
Damien Arrachequesne
parent
e95f6abf93
commit
be13cca94c
@@ -32,7 +32,11 @@ export type RawData = any;
|
||||
|
||||
export interface Packet {
|
||||
type: PacketType;
|
||||
options?: { compress: boolean };
|
||||
options?: {
|
||||
compress: boolean;
|
||||
wsPreEncoded?: string; // deprecated in favor of `wsPreEncodedFrame`
|
||||
wsPreEncodedFrame?: any; // computed in the socket.io-adapter package (should be typed as Buffer)
|
||||
};
|
||||
data?: RawData;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,27 +1,36 @@
|
||||
import { createServer } from "http";
|
||||
import { createServer, Server as HttpServer } from "http";
|
||||
import { Server, AttachOptions, ServerOptions } from "./server";
|
||||
import transports from "./transports/index";
|
||||
import * as parser from "engine.io-parser";
|
||||
|
||||
export { Server, transports, listen, attach, parser };
|
||||
export type { AttachOptions, ServerOptions, BaseServer } from "./server";
|
||||
export type {
|
||||
AttachOptions,
|
||||
ServerOptions,
|
||||
BaseServer,
|
||||
ErrorCallback,
|
||||
} from "./server";
|
||||
export { uServer } from "./userver";
|
||||
export { Socket } from "./socket";
|
||||
export { Transport } from "./transport";
|
||||
export const protocol = parser.protocol;
|
||||
|
||||
/**
|
||||
* Creates an http.Server exclusively used for WS upgrades.
|
||||
* Creates an http.Server exclusively used for WS upgrades, and starts listening.
|
||||
*
|
||||
* @param {Number} port
|
||||
* @param {Function} callback
|
||||
* @param {Object} options
|
||||
* @return {Server} websocket.io server
|
||||
* @param port
|
||||
* @param options
|
||||
* @param listenCallback - callback for http.Server.listen()
|
||||
* @return engine.io server
|
||||
*/
|
||||
|
||||
function listen(port, options: AttachOptions & ServerOptions, fn) {
|
||||
function listen(
|
||||
port: number,
|
||||
options?: AttachOptions & ServerOptions,
|
||||
listenCallback?: () => void,
|
||||
): Server {
|
||||
if ("function" === typeof options) {
|
||||
fn = options;
|
||||
listenCallback = options;
|
||||
options = {};
|
||||
}
|
||||
|
||||
@@ -34,7 +43,7 @@ function listen(port, options: AttachOptions & ServerOptions, fn) {
|
||||
const engine = attach(server, options);
|
||||
engine.httpServer = server;
|
||||
|
||||
server.listen(port, fn);
|
||||
server.listen(port, listenCallback);
|
||||
|
||||
return engine;
|
||||
}
|
||||
@@ -42,12 +51,15 @@ function listen(port, options: AttachOptions & ServerOptions, fn) {
|
||||
/**
|
||||
* Captures upgrade requests for a http.Server.
|
||||
*
|
||||
* @param {http.Server} server
|
||||
* @param {Object} options
|
||||
* @return {Server} engine server
|
||||
* @param server
|
||||
* @param options
|
||||
* @return engine.io server
|
||||
*/
|
||||
|
||||
function attach(server, options: AttachOptions & ServerOptions) {
|
||||
function attach(
|
||||
server: HttpServer,
|
||||
options: AttachOptions & ServerOptions,
|
||||
): Server {
|
||||
const engine = new Server(options);
|
||||
engine.attach(server, options);
|
||||
return engine;
|
||||
|
||||
@@ -59,8 +59,7 @@ const EMPTY_BUFFER = Buffer.concat([]);
|
||||
*
|
||||
* @api private
|
||||
*/
|
||||
|
||||
export function encodePacket (packet, supportsBinary, utf8encode, callback) {
|
||||
export function encodePacket (packet: any, supportsBinary?: any, utf8encode?: any, callback?: any) {
|
||||
if (typeof supportsBinary === 'function') {
|
||||
callback = supportsBinary;
|
||||
supportsBinary = null;
|
||||
@@ -86,7 +85,7 @@ export function encodePacket (packet, supportsBinary, utf8encode, callback) {
|
||||
}
|
||||
|
||||
return callback('' + encoded);
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Encode Buffer data
|
||||
@@ -120,16 +119,16 @@ export function encodeBase64Packet (packet, callback){
|
||||
/**
|
||||
* Decodes a packet. Data also available as an ArrayBuffer if requested.
|
||||
*
|
||||
* @return {Object} with `type` and `data` (if any)
|
||||
* @return {import('engine.io-parser').Packet} with `type` and `data` (if any)
|
||||
* @api private
|
||||
*/
|
||||
|
||||
export function decodePacket (data, binaryType, utf8decode) {
|
||||
export function decodePacket (data: any, binaryType?: any, utf8decode?: any): any {
|
||||
if (data === undefined) {
|
||||
return err;
|
||||
}
|
||||
|
||||
var type;
|
||||
let type: string | number;
|
||||
|
||||
// String data
|
||||
if (typeof data === 'string') {
|
||||
@@ -147,6 +146,7 @@ export function decodePacket (data, binaryType, utf8decode) {
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error
|
||||
if (Number(type) != type || !packetslist[type]) {
|
||||
return err;
|
||||
}
|
||||
@@ -274,7 +274,7 @@ function map(ary, each, done) {
|
||||
* @api public
|
||||
*/
|
||||
|
||||
export function decodePayload (data, binaryType, callback) {
|
||||
export function decodePayload (data: any, binaryType?: any, callback?: any) {
|
||||
if (typeof data !== 'string') {
|
||||
return decodePayloadAsBinary(data, binaryType, callback);
|
||||
}
|
||||
|
||||
@@ -6,7 +6,12 @@ import { EventEmitter } from "events";
|
||||
import { Socket } from "./socket";
|
||||
import debugModule from "debug";
|
||||
import { serialize } from "cookie";
|
||||
import { Server as DEFAULT_WS_ENGINE } from "ws";
|
||||
import {
|
||||
Server as DEFAULT_WS_ENGINE,
|
||||
type Server as WsServer,
|
||||
type PerMessageDeflateOptions,
|
||||
type WebSocket as WsWebSocket,
|
||||
} from "ws";
|
||||
import type {
|
||||
IncomingMessage,
|
||||
Server as HttpServer,
|
||||
@@ -16,14 +21,19 @@ import type { CorsOptions, CorsOptionsDelegate } from "cors";
|
||||
import type { Duplex } from "stream";
|
||||
import { WebTransport } from "./transports/webtransport";
|
||||
import { createPacketDecoderStream } from "engine.io-parser";
|
||||
import type { EngineRequest } from "./transport";
|
||||
import type { EngineRequest, Transport } from "./transport";
|
||||
import type { CookieSerializeOptions } from "./contrib/types.cookie";
|
||||
|
||||
const debug = debugModule("engine");
|
||||
|
||||
const kResponseHeaders = Symbol("responseHeaders");
|
||||
|
||||
type Transport = "polling" | "websocket" | "webtransport";
|
||||
type TransportName = "polling" | "websocket" | "webtransport";
|
||||
|
||||
export type ErrorCallback = (
|
||||
errorCode?: (typeof Server.errors)[keyof typeof Server.errors],
|
||||
errorContext?: Record<string, unknown> & { name?: string; message?: string },
|
||||
) => void;
|
||||
|
||||
export interface AttachOptions {
|
||||
/**
|
||||
@@ -90,7 +100,7 @@ export interface ServerOptions {
|
||||
*
|
||||
* @default ["polling", "websocket"]
|
||||
*/
|
||||
transports?: Transport[];
|
||||
transports?: TransportName[];
|
||||
/**
|
||||
* whether to allow transport upgrades
|
||||
* @default true
|
||||
@@ -100,7 +110,7 @@ export interface ServerOptions {
|
||||
* parameters of the WebSocket permessage-deflate extension (see ws module api docs). Set to false to disable.
|
||||
* @default false
|
||||
*/
|
||||
perMessageDeflate?: boolean | object;
|
||||
perMessageDeflate?: boolean | PerMessageDeflateOptions;
|
||||
/**
|
||||
* parameters of the http compression for the polling transports (see zlib api docs). Set to false to disable.
|
||||
* @default true
|
||||
@@ -149,7 +159,7 @@ type Middleware = (
|
||||
next: (err?: any) => void,
|
||||
) => void;
|
||||
|
||||
function parseSessionId(data: string) {
|
||||
function parseSessionId(data: string): string | undefined {
|
||||
try {
|
||||
const parsed = JSON.parse(data);
|
||||
if (typeof parsed.sid === "string") {
|
||||
@@ -224,7 +234,7 @@ export abstract class BaseServer extends EventEmitter {
|
||||
this.init();
|
||||
}
|
||||
|
||||
protected abstract init();
|
||||
protected abstract init(): void;
|
||||
|
||||
/**
|
||||
* Compute the pathname of the requests that are handled by the server
|
||||
@@ -244,10 +254,8 @@ export abstract class BaseServer extends EventEmitter {
|
||||
|
||||
/**
|
||||
* Returns a list of available transports for upgrade given a certain transport.
|
||||
*
|
||||
* @return {Array}
|
||||
*/
|
||||
public upgrades(transport: string) {
|
||||
public upgrades(transport: TransportName): string[] {
|
||||
if (!this.opts.allowUpgrades) return [];
|
||||
return transports[transport].upgradesTo || [];
|
||||
}
|
||||
@@ -259,17 +267,18 @@ export abstract class BaseServer extends EventEmitter {
|
||||
* @param upgrade - whether it's an upgrade request
|
||||
* @param fn
|
||||
* @protected
|
||||
* @return whether the request is valid
|
||||
*/
|
||||
protected verify(
|
||||
req: any,
|
||||
req: EngineRequest,
|
||||
upgrade: boolean,
|
||||
fn: (errorCode?: number, errorContext?: any) => void,
|
||||
) {
|
||||
fn: ErrorCallback,
|
||||
): void | boolean {
|
||||
// transport check
|
||||
const transport = req._query.transport;
|
||||
// WebTransport does not go through the verify() method, see the onWebTransportSession() method
|
||||
if (
|
||||
!~this.opts.transports.indexOf(transport) ||
|
||||
!~this.opts.transports.indexOf(transport as TransportName) ||
|
||||
transport === "webtransport"
|
||||
) {
|
||||
debug('unknown transport "%s"', transport);
|
||||
@@ -408,7 +417,7 @@ export abstract class BaseServer extends EventEmitter {
|
||||
*
|
||||
* @param {IncomingMessage} req - the request object
|
||||
*/
|
||||
public generateId(req: IncomingMessage) {
|
||||
public generateId(req: IncomingMessage): string | PromiseLike<string> {
|
||||
return base64id.generateId();
|
||||
}
|
||||
|
||||
@@ -422,9 +431,9 @@ export abstract class BaseServer extends EventEmitter {
|
||||
* @protected
|
||||
*/
|
||||
protected async handshake(
|
||||
transportName: string,
|
||||
req: any,
|
||||
closeConnection: (errorCode?: number, errorContext?: any) => void,
|
||||
transportName: TransportName,
|
||||
req: EngineRequest,
|
||||
closeConnection: ErrorCallback,
|
||||
) {
|
||||
const protocol = req._query.EIO === "4" ? 4 : 3; // 3rd revision by default
|
||||
if (protocol === 3 && !this.opts.allowEIO3) {
|
||||
@@ -600,7 +609,10 @@ export abstract class BaseServer extends EventEmitter {
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract createTransport(transportName, req);
|
||||
protected abstract createTransport(
|
||||
transportName: TransportName,
|
||||
req: EngineRequest,
|
||||
);
|
||||
|
||||
/**
|
||||
* Protocol errors mappings.
|
||||
@@ -613,7 +625,7 @@ export abstract class BaseServer extends EventEmitter {
|
||||
BAD_REQUEST: 3,
|
||||
FORBIDDEN: 4,
|
||||
UNSUPPORTED_PROTOCOL_VERSION: 5,
|
||||
};
|
||||
} as const;
|
||||
|
||||
static errorMessages = {
|
||||
0: "Transport unknown",
|
||||
@@ -622,7 +634,7 @@ export abstract class BaseServer extends EventEmitter {
|
||||
3: "Bad request",
|
||||
4: "Forbidden",
|
||||
5: "Unsupported protocol version",
|
||||
};
|
||||
} as const;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -667,7 +679,7 @@ class WebSocketResponse {
|
||||
*/
|
||||
export class Server extends BaseServer {
|
||||
public httpServer?: HttpServer;
|
||||
private ws: any;
|
||||
private ws: WsServer;
|
||||
|
||||
/**
|
||||
* Initialize websocket server
|
||||
@@ -687,7 +699,7 @@ export class Server extends BaseServer {
|
||||
});
|
||||
|
||||
if (typeof this.ws.on === "function") {
|
||||
this.ws.on("headers", (headersArray, req) => {
|
||||
this.ws.on("headers", (headersArray, req: EngineRequest) => {
|
||||
// note: 'ws' uses an array of headers, while Engine.IO uses an object (response.writeHead() accepts both formats)
|
||||
// we could also try to parse the array and then sync the values, but that will be error-prone
|
||||
const additionalHeaders = req[kResponseHeaders] || {};
|
||||
@@ -730,7 +742,11 @@ export class Server extends BaseServer {
|
||||
}
|
||||
}
|
||||
|
||||
protected createTransport(transportName: string, req: IncomingMessage) {
|
||||
protected createTransport(
|
||||
transportName: TransportName,
|
||||
req: IncomingMessage,
|
||||
): Transport {
|
||||
// @ts-expect-error 'polling' is a plain function used as constructor
|
||||
return new transports[transportName](req);
|
||||
}
|
||||
|
||||
@@ -745,7 +761,7 @@ export class Server extends BaseServer {
|
||||
this.prepare(req);
|
||||
req.res = res;
|
||||
|
||||
const callback = (errorCode, errorContext) => {
|
||||
const callback: ErrorCallback = (errorCode, errorContext) => {
|
||||
if (errorCode !== undefined) {
|
||||
this.emit("connection_error", {
|
||||
req,
|
||||
@@ -763,7 +779,11 @@ export class Server extends BaseServer {
|
||||
} else {
|
||||
const closeConnection = (errorCode, errorContext) =>
|
||||
abortRequest(res, errorCode, errorContext);
|
||||
this.handshake(req._query.transport, req, closeConnection);
|
||||
this.handshake(
|
||||
req._query.transport as TransportName,
|
||||
req,
|
||||
closeConnection,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -787,7 +807,7 @@ export class Server extends BaseServer {
|
||||
this.prepare(req);
|
||||
|
||||
const res = new WebSocketResponse(req, socket);
|
||||
const callback = (errorCode, errorContext) => {
|
||||
const callback: ErrorCallback = (errorCode, errorContext) => {
|
||||
if (errorCode !== undefined) {
|
||||
this.emit("connection_error", {
|
||||
req,
|
||||
@@ -823,11 +843,16 @@ export class Server extends BaseServer {
|
||||
|
||||
/**
|
||||
* Called upon a ws.io connection.
|
||||
*
|
||||
* @param {ws.Socket} websocket
|
||||
* @param req
|
||||
* @param socket
|
||||
* @param websocket
|
||||
* @private
|
||||
*/
|
||||
private onWebSocket(req, socket, websocket) {
|
||||
private onWebSocket(
|
||||
req: EngineRequest,
|
||||
socket: Duplex,
|
||||
websocket: WsWebSocket,
|
||||
) {
|
||||
websocket.on("error", onUpgradeError);
|
||||
|
||||
if (
|
||||
@@ -862,14 +887,22 @@ export class Server extends BaseServer {
|
||||
// transport error handling takes over
|
||||
websocket.removeListener("error", onUpgradeError);
|
||||
|
||||
const transport = this.createTransport(req._query.transport, req);
|
||||
const transport = this.createTransport(
|
||||
req._query.transport as TransportName,
|
||||
req,
|
||||
);
|
||||
// @ts-expect-error this option is only for WebSocket impl
|
||||
transport.perMessageDeflate = this.opts.perMessageDeflate;
|
||||
client._maybeUpgrade(transport);
|
||||
}
|
||||
} else {
|
||||
const closeConnection = (errorCode, errorContext) =>
|
||||
abortUpgrade(socket, errorCode, errorContext);
|
||||
this.handshake(req._query.transport, req, closeConnection);
|
||||
this.handshake(
|
||||
req._query.transport as TransportName,
|
||||
req,
|
||||
closeConnection,
|
||||
);
|
||||
}
|
||||
|
||||
function onUpgradeError() {
|
||||
@@ -947,7 +980,11 @@ export class Server extends BaseServer {
|
||||
* @private
|
||||
*/
|
||||
|
||||
function abortRequest(res, errorCode, errorContext) {
|
||||
function abortRequest(
|
||||
res: ServerResponse,
|
||||
errorCode: number,
|
||||
errorContext?: { message?: string },
|
||||
) {
|
||||
const statusCode = errorCode === Server.errors.FORBIDDEN ? 403 : 400;
|
||||
const message =
|
||||
errorContext && errorContext.message
|
||||
@@ -1030,7 +1067,7 @@ const validHdrChars = [
|
||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 // ... 255
|
||||
]
|
||||
|
||||
function checkInvalidHeaderChar(val) {
|
||||
function checkInvalidHeaderChar(val?: string) {
|
||||
val += "";
|
||||
if (val.length < 1) return false;
|
||||
if (!validHdrChars[val.charCodeAt(0)]) {
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { EngineRequest, Transport } from "./transport";
|
||||
import type { BaseServer } from "./server";
|
||||
import { setTimeout, clearTimeout } from "timers";
|
||||
import type { Packet, PacketType, RawData } from "engine.io-parser";
|
||||
import type transports from "./transports";
|
||||
|
||||
const debug = debugModule("engine:socket");
|
||||
|
||||
@@ -537,9 +538,11 @@ export class Socket extends EventEmitter {
|
||||
*/
|
||||
private getAvailableUpgrades() {
|
||||
const availableUpgrades = [];
|
||||
const allUpgrades = this.server.upgrades(this.transport.name);
|
||||
const allUpgrades = this.server.upgrades(
|
||||
this.transport.name as keyof typeof transports,
|
||||
);
|
||||
for (let i = 0; i < allUpgrades.length; ++i) {
|
||||
const upg = allUpgrades[i];
|
||||
const upg = allUpgrades[i] as keyof typeof transports;
|
||||
if (this.server.opts.transports.indexOf(upg) !== -1) {
|
||||
availableUpgrades.push(upg);
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import * as parser_v3 from "./parser-v3/index";
|
||||
import debugModule from "debug";
|
||||
import type { IncomingMessage, ServerResponse } from "http";
|
||||
import { Packet, RawData } from "engine.io-parser";
|
||||
import type { WebSocket } from "ws";
|
||||
|
||||
const debug = debugModule("engine:transport");
|
||||
|
||||
@@ -15,7 +16,11 @@ export type EngineRequest = IncomingMessage & {
|
||||
_query: Record<string, string>;
|
||||
res?: ServerResponse;
|
||||
cleanup?: Function;
|
||||
websocket?: any;
|
||||
websocket?: WebSocket & {
|
||||
_socket?: {
|
||||
remoteAddress: string;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
export abstract class Transport extends EventEmitter {
|
||||
@@ -37,7 +42,7 @@ export abstract class Transport extends EventEmitter {
|
||||
*
|
||||
* @see https://github.com/socketio/engine.io-protocol
|
||||
*/
|
||||
public protocol: number;
|
||||
public protocol: 3 | 4;
|
||||
|
||||
/**
|
||||
* The current state of the transport.
|
||||
@@ -53,7 +58,7 @@ export abstract class Transport extends EventEmitter {
|
||||
* The parser to use (depends on the revision of the {@link Transport#protocol}.
|
||||
* @protected
|
||||
*/
|
||||
protected parser: any;
|
||||
protected parser: typeof parser_v4 | typeof parser_v3;
|
||||
/**
|
||||
* Whether the transport supports binary payloads (else it will be base64-encoded)
|
||||
* @protected
|
||||
@@ -74,6 +79,11 @@ export abstract class Transport extends EventEmitter {
|
||||
this._readyState = state;
|
||||
}
|
||||
|
||||
/**
|
||||
* The list of transports this transport can be upgraded to.
|
||||
*/
|
||||
static upgradesTo: string[] = [];
|
||||
|
||||
/**
|
||||
* Transport constructor.
|
||||
*
|
||||
@@ -148,7 +158,7 @@ export abstract class Transport extends EventEmitter {
|
||||
/**
|
||||
* Called with the encoded packet data.
|
||||
*
|
||||
* @param {String} data
|
||||
* @param data
|
||||
* @protected
|
||||
*/
|
||||
protected onData(data: RawData) {
|
||||
|
||||
@@ -3,6 +3,8 @@ import { createGzip, createDeflate } from "zlib";
|
||||
import * as accepts from "accepts";
|
||||
import debugModule from "debug";
|
||||
import { HttpRequest, HttpResponse } from "uWebSockets.js";
|
||||
import type * as parser_v4 from "engine.io-parser";
|
||||
import type * as parser_v3 from "../parser-v3/index";
|
||||
|
||||
const debug = debugModule("engine:polling");
|
||||
|
||||
@@ -228,9 +230,9 @@ export class Polling extends Transport {
|
||||
};
|
||||
|
||||
if (this.protocol === 3) {
|
||||
this.parser.decodePayload(data, callback);
|
||||
(this.parser as typeof parser_v3).decodePayload(data, callback);
|
||||
} else {
|
||||
this.parser.decodePayload(data).forEach(callback);
|
||||
(this.parser as typeof parser_v4).decodePayload(data).forEach(callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,7 +265,7 @@ export class Polling extends Transport {
|
||||
this.shouldClose = null;
|
||||
}
|
||||
|
||||
const doWrite = (data) => {
|
||||
const doWrite = (data: string) => {
|
||||
const compress = packets.some((packet) => {
|
||||
return packet.options && packet.options.compress;
|
||||
});
|
||||
@@ -271,9 +273,13 @@ export class Polling extends Transport {
|
||||
};
|
||||
|
||||
if (this.protocol === 3) {
|
||||
this.parser.encodePayload(packets, this.supportsBinary, doWrite);
|
||||
(this.parser as typeof parser_v3).encodePayload(
|
||||
packets,
|
||||
this.supportsBinary,
|
||||
doWrite,
|
||||
);
|
||||
} else {
|
||||
this.parser.encodePayload(packets, doWrite);
|
||||
(this.parser as typeof parser_v4).encodePayload(packets, doWrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,10 @@ import { Polling as XHR } from "./polling";
|
||||
import { JSONP } from "./polling-jsonp";
|
||||
import { WebSocket } from "./websocket";
|
||||
import { WebTransport } from "./webtransport";
|
||||
import type { EngineRequest } from "../transport";
|
||||
|
||||
export default {
|
||||
polling: polling,
|
||||
polling,
|
||||
websocket: WebSocket,
|
||||
webtransport: WebTransport,
|
||||
};
|
||||
@@ -12,8 +13,7 @@ export default {
|
||||
/**
|
||||
* Polling polymorphic constructor.
|
||||
*/
|
||||
|
||||
function polling(req) {
|
||||
function polling(req: EngineRequest) {
|
||||
if ("string" === typeof req._query.j) {
|
||||
return new JSONP(req);
|
||||
} else {
|
||||
|
||||
@@ -4,6 +4,8 @@ import * as accepts from "accepts";
|
||||
import debugModule from "debug";
|
||||
import type { IncomingMessage, ServerResponse } from "http";
|
||||
import type { Packet, RawData } from "engine.io-parser";
|
||||
import type * as parser_v4 from "engine.io-parser";
|
||||
import type * as parser_v3 from "../parser-v3/index";
|
||||
|
||||
const debug = debugModule("engine:polling");
|
||||
|
||||
@@ -196,9 +198,9 @@ export class Polling extends Transport {
|
||||
};
|
||||
|
||||
if (this.protocol === 3) {
|
||||
this.parser.decodePayload(data, callback);
|
||||
(this.parser as typeof parser_v3).decodePayload(data, callback);
|
||||
} else {
|
||||
this.parser.decodePayload(data).forEach(callback);
|
||||
(this.parser as typeof parser_v4).decodePayload(data).forEach(callback);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,7 +227,7 @@ export class Polling extends Transport {
|
||||
this.shouldClose = null;
|
||||
}
|
||||
|
||||
const doWrite = (data) => {
|
||||
const doWrite = (data: string) => {
|
||||
const compress = packets.some((packet) => {
|
||||
return packet.options && packet.options.compress;
|
||||
});
|
||||
@@ -233,9 +235,13 @@ export class Polling extends Transport {
|
||||
};
|
||||
|
||||
if (this.protocol === 3) {
|
||||
this.parser.encodePayload(packets, this.supportsBinary, doWrite);
|
||||
(this.parser as typeof parser_v3).encodePayload(
|
||||
packets,
|
||||
this.supportsBinary,
|
||||
doWrite,
|
||||
);
|
||||
} else {
|
||||
this.parser.encodePayload(packets, doWrite);
|
||||
(this.parser as typeof parser_v4).encodePayload(packets, doWrite);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
import { EngineRequest, Transport } from "../transport";
|
||||
import debugModule from "debug";
|
||||
import type { Packet, RawData } from "engine.io-parser";
|
||||
import type { PerMessageDeflateOptions, WebSocket as WsWebSocket } from "ws";
|
||||
|
||||
const debug = debugModule("engine:ws");
|
||||
|
||||
export class WebSocket extends Transport {
|
||||
protected perMessageDeflate: any;
|
||||
private socket: any;
|
||||
perMessageDeflate?: boolean | PerMessageDeflateOptions;
|
||||
private socket: WsWebSocket;
|
||||
|
||||
/**
|
||||
* WebSocket transport
|
||||
@@ -51,8 +52,8 @@ export class WebSocket extends Transport {
|
||||
if (this._canSendPreEncodedFrame(packet)) {
|
||||
// the WebSocket frame was computed with WebSocket.Sender.frame()
|
||||
// see https://github.com/websockets/ws/issues/617#issuecomment-283002469
|
||||
// @ts-expect-error use of untyped member
|
||||
this.socket._sender.sendFrame(
|
||||
// @ts-ignore
|
||||
packet.options.wsPreEncodedFrame,
|
||||
isLast ? this._onSentLast : this._onSent,
|
||||
);
|
||||
@@ -74,8 +75,8 @@ export class WebSocket extends Transport {
|
||||
private _canSendPreEncodedFrame(packet: Packet) {
|
||||
return (
|
||||
!this.perMessageDeflate &&
|
||||
// @ts-expect-error use of untyped member
|
||||
typeof this.socket?._sender?.sendFrame === "function" &&
|
||||
// @ts-ignore
|
||||
packet.options?.wsPreEncodedFrame !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@ import debugModule from "debug";
|
||||
import { AttachOptions, BaseServer, Server } from "./server";
|
||||
import { HttpRequest, HttpResponse, TemplatedApp } from "uWebSockets.js";
|
||||
import transports from "./transports-uws";
|
||||
import { EngineRequest } from "./transport";
|
||||
|
||||
const debug = debugModule("engine:uws");
|
||||
|
||||
@@ -36,7 +37,7 @@ export class uServer extends BaseServer {
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private prepare(req, res: HttpResponse) {
|
||||
private prepare(req: HttpRequest & EngineRequest, res: HttpResponse) {
|
||||
req.method = req.getMethod().toUpperCase();
|
||||
req.url = req.getUrl();
|
||||
|
||||
@@ -48,6 +49,7 @@ export class uServer extends BaseServer {
|
||||
req.headers[key] = value;
|
||||
});
|
||||
|
||||
// @ts-expect-error
|
||||
req.connection = {
|
||||
remoteAddress: Buffer.from(res.getRemoteAddressAsText()).toString(),
|
||||
};
|
||||
@@ -57,7 +59,7 @@ export class uServer extends BaseServer {
|
||||
});
|
||||
}
|
||||
|
||||
protected createTransport(transportName, req) {
|
||||
protected createTransport(transportName: string, req: EngineRequest) {
|
||||
return new transports[transportName](req);
|
||||
}
|
||||
|
||||
@@ -123,7 +125,7 @@ export class uServer extends BaseServer {
|
||||
req: HttpRequest & { res: any; _query: any },
|
||||
) {
|
||||
debug('handling "%s" http request "%s"', req.getMethod(), req.getUrl());
|
||||
this.prepare(req, res);
|
||||
this.prepare(req as unknown as HttpRequest & EngineRequest, res);
|
||||
|
||||
req.res = res;
|
||||
|
||||
@@ -146,7 +148,11 @@ export class uServer extends BaseServer {
|
||||
} else {
|
||||
const closeConnection = (errorCode, errorContext) =>
|
||||
this.abortRequest(res, errorCode, errorContext);
|
||||
this.handshake(req._query.transport, req, closeConnection);
|
||||
this.handshake(
|
||||
req._query.transport,
|
||||
req as unknown as EngineRequest,
|
||||
closeConnection,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -154,7 +160,11 @@ export class uServer extends BaseServer {
|
||||
if (err) {
|
||||
callback(Server.errors.BAD_REQUEST, { name: "MIDDLEWARE_FAILURE" });
|
||||
} else {
|
||||
this.verify(req, false, callback);
|
||||
this.verify(
|
||||
req as unknown as HttpRequest & EngineRequest,
|
||||
false,
|
||||
callback,
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -166,7 +176,7 @@ export class uServer extends BaseServer {
|
||||
) {
|
||||
debug("on upgrade");
|
||||
|
||||
this.prepare(req, res);
|
||||
this.prepare(req as unknown as HttpRequest & EngineRequest, res);
|
||||
|
||||
req.res = res;
|
||||
|
||||
@@ -198,13 +208,16 @@ export class uServer extends BaseServer {
|
||||
return res.close();
|
||||
} else {
|
||||
debug("upgrading existing transport");
|
||||
transport = this.createTransport(req._query.transport, req);
|
||||
transport = this.createTransport(
|
||||
req._query.transport,
|
||||
req as unknown as EngineRequest,
|
||||
);
|
||||
client._maybeUpgrade(transport);
|
||||
}
|
||||
} else {
|
||||
transport = await this.handshake(
|
||||
req._query.transport,
|
||||
req,
|
||||
req as unknown as EngineRequest,
|
||||
(errorCode, errorContext) =>
|
||||
this.abortRequest(res, errorCode, errorContext),
|
||||
);
|
||||
@@ -231,15 +244,15 @@ export class uServer extends BaseServer {
|
||||
if (err) {
|
||||
callback(Server.errors.BAD_REQUEST, { name: "MIDDLEWARE_FAILURE" });
|
||||
} else {
|
||||
this.verify(req, true, callback);
|
||||
this.verify(req as unknown as EngineRequest, true, callback);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private abortRequest(
|
||||
res: HttpResponse | ResponseWrapper,
|
||||
errorCode,
|
||||
errorContext,
|
||||
errorCode: number,
|
||||
errorContext?: { message?: string },
|
||||
) {
|
||||
const statusCode =
|
||||
errorCode === Server.errors.FORBIDDEN
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { EventEmitter } from "events";
|
||||
import { yeast } from "./contrib/yeast";
|
||||
import WebSocket = require("ws");
|
||||
import * as WebSocket from "ws";
|
||||
|
||||
// @ts-expect-error
|
||||
const canPreComputeFrame = typeof WebSocket?.Sender?.frame === "function";
|
||||
@@ -51,11 +51,11 @@ export class Adapter extends EventEmitter {
|
||||
/**
|
||||
* In-memory adapter constructor.
|
||||
*
|
||||
* @param {Namespace} nsp
|
||||
* @param nsp
|
||||
*/
|
||||
constructor(readonly nsp: any) {
|
||||
super();
|
||||
this.encoder = nsp.server.encoder;
|
||||
this.encoder = nsp.server.encoder; // nsp is a Namespace object
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
import { Server, type ServerOptions, Socket, type Transport } from "engine.io";
|
||||
import {
|
||||
Server,
|
||||
type ServerOptions,
|
||||
type ErrorCallback,
|
||||
Socket,
|
||||
type Transport,
|
||||
} from "engine.io";
|
||||
import { randomBytes } from "node:crypto";
|
||||
import { setTimeout, clearTimeout } from "node:timers";
|
||||
import { type IncomingMessage } from "node:http";
|
||||
@@ -392,9 +398,9 @@ export abstract class ClusterEngine extends Server {
|
||||
override verify(
|
||||
req: IncomingMessage & { _query: Record<string, string> },
|
||||
upgrade: boolean,
|
||||
fn: (errorCode?: number, context?: any) => void,
|
||||
fn: ErrorCallback,
|
||||
): void {
|
||||
super.verify(req, upgrade, (errorCode: number, errorContext: any) => {
|
||||
super.verify(req, upgrade, (errorCode, errorContext) => {
|
||||
if (errorCode !== Server.errors.UNKNOWN_SID) {
|
||||
return fn(errorCode, errorContext);
|
||||
}
|
||||
@@ -412,7 +418,7 @@ export abstract class ClusterEngine extends Server {
|
||||
req[kSenderId] = senderId;
|
||||
fn();
|
||||
} else {
|
||||
const transport = this.createTransport(transportName, req);
|
||||
const transport = this.createTransport(transportName as any, req);
|
||||
this._hookTransport(sid, transport, lockType, senderId);
|
||||
transport.onRequest(req);
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Decoder, Encoder, Packet, PacketType } from "socket.io-parser";
|
||||
import debugModule = require("debug");
|
||||
import url = require("url");
|
||||
import debugModule from "debug";
|
||||
import url from "url";
|
||||
import type { IncomingMessage } from "http";
|
||||
import type { Server } from "./index";
|
||||
import type { Namespace } from "./namespace";
|
||||
@@ -61,12 +61,13 @@ export class Client<
|
||||
*/
|
||||
constructor(
|
||||
server: Server<ListenEvents, EmitEvents, ServerSideEvents, SocketData>,
|
||||
conn: any,
|
||||
conn: RawSocket,
|
||||
) {
|
||||
this.server = server;
|
||||
this.conn = conn;
|
||||
this.encoder = server.encoder;
|
||||
this.decoder = new server._parser.Decoder();
|
||||
// @ts-expect-error use of private
|
||||
this.id = conn.id;
|
||||
this.setup();
|
||||
}
|
||||
@@ -216,13 +217,13 @@ export class Client<
|
||||
* @param {Object} opts
|
||||
* @private
|
||||
*/
|
||||
_packet(packet: Packet | any[], opts: WriteOptions = {}): void {
|
||||
_packet(packet: Packet | Packet[], opts: WriteOptions = {}): void {
|
||||
if (this.conn.readyState !== "open") {
|
||||
debug("ignoring packet write %j", packet);
|
||||
return;
|
||||
}
|
||||
const encodedPackets = opts.preEncoded
|
||||
? (packet as any[]) // previous versions of the adapter incorrectly used socket.packet() instead of writeToEngine()
|
||||
? (packet as Packet[]) // previous versions of the adapter incorrectly used socket.packet() instead of writeToEngine()
|
||||
: this.encoder.encode(packet as Packet);
|
||||
this.writeToEngine(encodedPackets, opts);
|
||||
}
|
||||
@@ -250,7 +251,7 @@ export class Client<
|
||||
*
|
||||
* @private
|
||||
*/
|
||||
private ondata(data): void {
|
||||
private ondata(data: unknown): void {
|
||||
// try/catch is needed for protocol violations (GH-1880)
|
||||
try {
|
||||
this.decoder.add(data);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import http = require("http");
|
||||
import http from "http";
|
||||
import type { Server as HTTPSServer } from "https";
|
||||
import type { Http2SecureServer, Http2Server } from "http2";
|
||||
import { createReadStream } from "fs";
|
||||
@@ -7,7 +7,11 @@ import accepts = require("accepts");
|
||||
import { pipeline } from "stream";
|
||||
import path = require("path");
|
||||
import { attach, Server as Engine, uServer } from "engine.io";
|
||||
import type { ServerOptions as EngineOptions, AttachOptions } from "engine.io";
|
||||
import type {
|
||||
ServerOptions as EngineOptions,
|
||||
AttachOptions,
|
||||
Socket as RawSocket,
|
||||
} from "engine.io";
|
||||
import { Client } from "./client";
|
||||
import { EventEmitter } from "events";
|
||||
import { ExtendedError, Namespace, ServerReservedEventsMap } from "./namespace";
|
||||
@@ -506,6 +510,11 @@ export class Server<
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches socket.io to a uWebSockets.js app.
|
||||
* @param app
|
||||
* @param opts
|
||||
*/
|
||||
public attachApp(app /*: TemplatedApp */, opts: Partial<ServerOptions> = {}) {
|
||||
// merge the options passed to the Socket.IO server
|
||||
Object.assign(opts, this.opts);
|
||||
@@ -582,7 +591,7 @@ export class Server<
|
||||
): void {
|
||||
// initialize engine
|
||||
debug("creating engine.io instance with opts %j", opts);
|
||||
this.eio = attach(srv, opts);
|
||||
this.eio = attach(srv as http.Server, opts);
|
||||
|
||||
// attach static file serving
|
||||
if (this._serveClient) this.attachServe(srv);
|
||||
@@ -723,11 +732,12 @@ export class Server<
|
||||
* @return self
|
||||
* @private
|
||||
*/
|
||||
private onconnection(conn): this {
|
||||
private onconnection(conn: RawSocket): this {
|
||||
// @ts-expect-error use of private
|
||||
debug("incoming connection with id %s", conn.id);
|
||||
const client = new Client(this, conn);
|
||||
if (conn.protocol === 3) {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error use of private
|
||||
client.connect("/");
|
||||
}
|
||||
return this;
|
||||
|
||||
@@ -163,7 +163,7 @@ export class Socket<
|
||||
) {
|
||||
super();
|
||||
this.server = nsp.server;
|
||||
this.adapter = this.nsp.adapter;
|
||||
this.adapter = nsp.adapter;
|
||||
if (previousSession) {
|
||||
this.id = previousSession.sid;
|
||||
this.pid = previousSession.pid;
|
||||
|
||||
Reference in New Issue
Block a user