engine.io
Advanced tools
Comparing version 6.4.2 to 6.5.0-alpha.1
@@ -59,3 +59,9 @@ /// <reference types="node" /> | ||
/** | ||
* the low-level transports that are enabled | ||
* The low-level transports that are enabled. WebTransport is disabled by default and must be manually enabled: | ||
* | ||
* @example | ||
* new Server({ | ||
* transports: ["polling", "websocket", "webtransport"] | ||
* }); | ||
* | ||
* @default ["polling", "websocket"] | ||
@@ -197,2 +203,3 @@ */ | ||
protected handshake(transportName: any, req: any, closeConnection: any): Promise<any>; | ||
onWebTransportSession(session: any): Promise<any>; | ||
protected abstract createTransport(transportName: any, req: any): any; | ||
@@ -199,0 +206,0 @@ /** |
@@ -13,4 +13,17 @@ "use strict"; | ||
const ws_1 = require("ws"); | ||
const webtransport_1 = require("./transports/webtransport"); | ||
const debug = (0, debug_1.default)("engine"); | ||
const kResponseHeaders = Symbol("responseHeaders"); | ||
const TEXT_DECODER = new TextDecoder(); | ||
function parseSessionId(handshake) { | ||
if (handshake.startsWith("0{")) { | ||
try { | ||
const parsed = JSON.parse(handshake.substring(1)); | ||
if (typeof parsed.sid === "string") { | ||
return parsed.sid; | ||
} | ||
} | ||
catch (e) { } | ||
} | ||
} | ||
class BaseServer extends events_1.EventEmitter { | ||
@@ -34,3 +47,3 @@ /** | ||
maxHttpBufferSize: 1e6, | ||
transports: Object.keys(transports_1.default), | ||
transports: ["polling", "websocket"], | ||
allowUpgrades: true, | ||
@@ -96,3 +109,5 @@ httpCompression: { | ||
const transport = req._query.transport; | ||
if (!~this.opts.transports.indexOf(transport)) { | ||
// WebTransport does not go through the verify() method, see the onWebTransportSession() method | ||
if (!~this.opts.transports.indexOf(transport) || | ||
transport === "webtransport") { | ||
debug('unknown transport "%s"', transport); | ||
@@ -321,2 +336,65 @@ return fn(Server.errors.UNKNOWN_TRANSPORT, { transport }); | ||
} | ||
async onWebTransportSession(session) { | ||
const timeout = setTimeout(() => { | ||
debug("the client failed to establish a bidirectional stream in the given period"); | ||
session.close(); | ||
}, this.opts.upgradeTimeout); | ||
const streamReader = session.incomingBidirectionalStreams.getReader(); | ||
const result = await streamReader.read(); | ||
if (result.done) { | ||
debug("session is closed"); | ||
return; | ||
} | ||
const stream = result.value; | ||
const reader = stream.readable.getReader(); | ||
// reading the first packet of the stream | ||
const { value, done } = await reader.read(); | ||
if (done) { | ||
debug("stream is closed"); | ||
return; | ||
} | ||
clearTimeout(timeout); | ||
const handshake = TEXT_DECODER.decode(value); | ||
// handshake is either | ||
// "0" => new session | ||
// '0{"sid":"xxxx"}' => upgrade | ||
if (handshake === "0") { | ||
const transport = new webtransport_1.WebTransport(session, stream, reader); | ||
// note: we cannot use "this.generateId()", because there is no "req" argument | ||
const id = base64id.generateId(); | ||
debug('handshaking client "%s" (WebTransport)', id); | ||
const socket = new socket_1.Socket(id, this, transport, null, 4); | ||
this.clients[id] = socket; | ||
this.clientsCount++; | ||
socket.once("close", () => { | ||
delete this.clients[id]; | ||
this.clientsCount--; | ||
}); | ||
this.emit("connection", socket); | ||
return; | ||
} | ||
const sid = parseSessionId(handshake); | ||
if (!sid) { | ||
debug("invalid WebTransport handshake"); | ||
return session.close(); | ||
} | ||
const client = this.clients[sid]; | ||
if (!client) { | ||
debug("upgrade attempt for closed client"); | ||
session.close(); | ||
} | ||
else if (client.upgrading) { | ||
debug("transport has already been trying to upgrade"); | ||
session.close(); | ||
} | ||
else if (client.upgraded) { | ||
debug("transport had already been upgraded"); | ||
session.close(); | ||
} | ||
else { | ||
debug("upgrading existing transport"); | ||
const transport = new webtransport_1.WebTransport(session, stream, reader); | ||
client.maybeUpgrade(transport); | ||
} | ||
} | ||
} | ||
@@ -323,0 +401,0 @@ exports.BaseServer = BaseServer; |
@@ -28,7 +28,13 @@ "use strict"; | ||
// Cache IP since it might not be in the req later | ||
if (req.websocket && req.websocket._socket) { | ||
this.remoteAddress = req.websocket._socket.remoteAddress; | ||
if (req) { | ||
if (req.websocket && req.websocket._socket) { | ||
this.remoteAddress = req.websocket._socket.remoteAddress; | ||
} | ||
else { | ||
this.remoteAddress = req.connection.remoteAddress; | ||
} | ||
} | ||
else { | ||
this.remoteAddress = req.connection.remoteAddress; | ||
// TODO there is currently no way to get the IP address of the client when it connects with WebTransport | ||
// see https://github.com/fails-components/webtransport/issues/114 | ||
} | ||
@@ -35,0 +41,0 @@ this.checkIntervalTimer = null; |
@@ -72,6 +72,21 @@ /// <reference types="node" /> | ||
protected onClose(): void; | ||
/** | ||
* Advertise framing support. | ||
*/ | ||
abstract get supportsFraming(): any; | ||
/** | ||
* The name of the transport. | ||
*/ | ||
abstract get name(): any; | ||
/** | ||
* Sends an array of packets. | ||
* | ||
* @param {Array} packets | ||
* @package | ||
*/ | ||
abstract send(packets: any): any; | ||
/** | ||
* Closes the transport. | ||
*/ | ||
abstract doClose(fn?: any): any; | ||
} |
import { Polling as XHR } from "./polling"; | ||
import { WebSocket } from "./websocket"; | ||
import { WebTransport } from "./webtransport"; | ||
declare const _default: { | ||
polling: typeof polling; | ||
websocket: typeof WebSocket; | ||
webtransport: typeof WebTransport; | ||
}; | ||
@@ -7,0 +9,0 @@ export default _default; |
@@ -6,5 +6,7 @@ "use strict"; | ||
const websocket_1 = require("./websocket"); | ||
const webtransport_1 = require("./webtransport"); | ||
exports.default = { | ||
polling: polling, | ||
websocket: websocket_1.WebSocket, | ||
webtransport: webtransport_1.WebTransport, | ||
}; | ||
@@ -24,2 +26,2 @@ /** | ||
} | ||
polling.upgradesTo = ["websocket"]; | ||
polling.upgradesTo = ["websocket", "webtransport"]; |
@@ -189,2 +189,3 @@ "use strict"; | ||
this.headers = []; | ||
this.isAborted = false; | ||
} | ||
@@ -217,2 +218,4 @@ set statusCode(status) { | ||
writeStatus(status) { | ||
if (this.isAborted) | ||
return; | ||
this.res.writeStatus(status); | ||
@@ -224,2 +227,4 @@ this.statusWritten = true; | ||
writeHeader(key, value) { | ||
if (this.isAborted) | ||
return; | ||
if (key === "Content-Length") { | ||
@@ -242,2 +247,4 @@ // the content length is automatically added by uWebSockets.js | ||
end(data) { | ||
if (this.isAborted) | ||
return; | ||
if (!this.statusWritten) { | ||
@@ -250,7 +257,15 @@ // status will be inferred as "200 OK" | ||
onData(fn) { | ||
if (this.isAborted) | ||
return; | ||
this.res.onData(fn); | ||
} | ||
onAborted(fn) { | ||
this.res.onAborted(fn); | ||
if (this.isAborted) | ||
return; | ||
this.res.onAborted(() => { | ||
// Any attempt to use the UWS response object after abort will throw! | ||
this.isAborted = true; | ||
fn(); | ||
}); | ||
} | ||
} |
{ | ||
"name": "engine.io", | ||
"version": "6.4.2", | ||
"version": "6.5.0-alpha.1", | ||
"description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server", | ||
@@ -42,6 +42,7 @@ "type": "commonjs", | ||
"debug": "~4.3.1", | ||
"engine.io-parser": "~5.0.3", | ||
"engine.io-parser": "~5.1.0", | ||
"ws": "~8.11.0" | ||
}, | ||
"devDependencies": { | ||
"@fails-components/webtransport": "^0.1.7", | ||
"babel-eslint": "^8.0.2", | ||
@@ -55,2 +56,3 @@ "eiows": "^4.1.2", | ||
"mocha": "^9.1.3", | ||
"node-forge": "^1.3.1", | ||
"prettier": "^2.8.2", | ||
@@ -69,4 +71,4 @@ "rimraf": "^3.0.2", | ||
"test:uws": "EIO_WS_ENGINE=uws mocha --exit", | ||
"format:check": "prettier --check \"wrapper.mjs\" \"lib/**/*.ts\" \"test/**/*.js\"", | ||
"format:fix": "prettier --write \"wrapper.mjs\" \"lib/**/*.ts\" \"test/**/*.js\"", | ||
"format:check": "prettier --check \"wrapper.mjs\" \"lib/**/*.ts\" \"test/**/*.js\" \"test/webtransport.mjs\"", | ||
"format:fix": "prettier --write \"wrapper.mjs\" \"lib/**/*.ts\" \"test/**/*.js\" \"test/webtransport.mjs\"", | ||
"prepack": "npm run compile" | ||
@@ -73,0 +75,0 @@ }, |
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
162537
34
4476
15
1
+ Addedengine.io-parser@5.1.0(transitive)
- Removedengine.io-parser@5.0.7(transitive)
Updatedengine.io-parser@~5.1.0