engine.io
Advanced tools
Comparing version 5.0.0 to 5.1.0
@@ -0,1 +1,16 @@ | ||
# [5.1.0](https://github.com/socketio/engine.io/compare/5.0.0...5.1.0) (2021-05-04) | ||
### Features | ||
* add a "connection_error" event ([7096e98](https://github.com/socketio/engine.io/commit/7096e98a02295a62c8ea2aa56461d4875887092d)) | ||
* add the "initial_headers" and "headers" events ([2527543](https://github.com/socketio/engine.io/commit/252754353a0e88eb036ebb3082e9d6a9a5f497db)) | ||
### Performance Improvements | ||
* **websocket:** add a "wsPreEncoded" writing option ([7706b12](https://github.com/socketio/engine.io/commit/7706b123df914777d19c8179b45ab6932f82916c)) | ||
* **websocket:** fix write back-pressure ([#618](https://github.com/socketio/engine.io/issues/618)) ([ad5306a](https://github.com/socketio/engine.io/commit/ad5306aeaedf06ac7a49f791e1b76e55c35a564e)) | ||
# [5.0.0](https://github.com/socketio/engine.io/compare/4.1.1...5.0.0) (2021-03-10) | ||
@@ -2,0 +17,0 @@ |
@@ -87,2 +87,21 @@ const qs = require("querystring"); | ||
}); | ||
if (typeof this.ws.on === "function") { | ||
this.ws.on("headers", (headersArray, req) => { | ||
// 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 = {}; | ||
const isInitialRequest = !req._query.sid; | ||
if (isInitialRequest) { | ||
this.emit("initial_headers", additionalHeaders, req); | ||
} | ||
this.emit("headers", additionalHeaders, req); | ||
Object.keys(additionalHeaders).forEach(key => { | ||
headersArray.push(`${key}: ${additionalHeaders[key]}`); | ||
}); | ||
}); | ||
} | ||
} | ||
@@ -113,3 +132,3 @@ | ||
debug('unknown transport "%s"', transport); | ||
return fn(Server.errors.UNKNOWN_TRANSPORT, false); | ||
return fn(Server.errors.UNKNOWN_TRANSPORT, { transport }); | ||
} | ||
@@ -120,5 +139,9 @@ | ||
if (isOriginInvalid) { | ||
const origin = req.headers.origin; | ||
req.headers.origin = null; | ||
debug("origin header invalid"); | ||
return fn(Server.errors.BAD_REQUEST, false); | ||
return fn(Server.errors.BAD_REQUEST, { | ||
name: "INVALID_ORIGIN", | ||
origin | ||
}); | ||
} | ||
@@ -131,17 +154,36 @@ | ||
debug('unknown sid "%s"', sid); | ||
return fn(Server.errors.UNKNOWN_SID, false); | ||
return fn(Server.errors.UNKNOWN_SID, { | ||
sid | ||
}); | ||
} | ||
if (!upgrade && this.clients[sid].transport.name !== transport) { | ||
const previousTransport = this.clients[sid].transport.name; | ||
if (!upgrade && previousTransport !== transport) { | ||
debug("bad request: unexpected transport without upgrade"); | ||
return fn(Server.errors.BAD_REQUEST, false); | ||
return fn(Server.errors.BAD_REQUEST, { | ||
name: "TRANSPORT_MISMATCH", | ||
transport, | ||
previousTransport | ||
}); | ||
} | ||
} else { | ||
// handshake is GET only | ||
if ("GET" !== req.method) | ||
return fn(Server.errors.BAD_HANDSHAKE_METHOD, false); | ||
if (!this.opts.allowRequest) return fn(null, true); | ||
return this.opts.allowRequest(req, fn); | ||
if ("GET" !== req.method) { | ||
return fn(Server.errors.BAD_HANDSHAKE_METHOD, { | ||
method: req.method | ||
}); | ||
} | ||
if (!this.opts.allowRequest) return fn(); | ||
return this.opts.allowRequest(req, (message, success) => { | ||
if (!success) { | ||
return fn(Server.errors.FORBIDDEN, { | ||
message | ||
}); | ||
} | ||
fn(); | ||
}); | ||
} | ||
fn(null, true); | ||
fn(); | ||
} | ||
@@ -193,5 +235,11 @@ | ||
const callback = (err, success) => { | ||
if (!success) { | ||
sendErrorMessage(req, res, err); | ||
const callback = (errorCode, errorContext) => { | ||
if (errorCode !== undefined) { | ||
this.emit("connection_error", { | ||
req, | ||
code: errorCode, | ||
message: Server.errorMessages[errorCode], | ||
context: errorContext | ||
}); | ||
sendErrorMessage(req, res, errorCode, errorContext); | ||
return; | ||
@@ -239,2 +287,11 @@ } | ||
debug("unsupported protocol version"); | ||
this.emit("connection_error", { | ||
req, | ||
code: Server.errors.UNSUPPORTED_PROTOCOL_VERSION, | ||
message: | ||
Server.errorMessages[Server.errors.UNSUPPORTED_PROTOCOL_VERSION], | ||
context: { | ||
protocol | ||
} | ||
}); | ||
sendErrorMessage( | ||
@@ -253,2 +310,11 @@ req, | ||
debug("error while generating an id"); | ||
this.emit("connection_error", { | ||
req, | ||
code: Server.errors.BAD_REQUEST, | ||
message: Server.errorMessages[Server.errors.BAD_REQUEST], | ||
context: { | ||
name: "ID_GENERATION_ERROR", | ||
error: e | ||
} | ||
}); | ||
sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST); | ||
@@ -276,2 +342,11 @@ return; | ||
debug('error handshaking to transport "%s"', transportName); | ||
this.emit("connection_error", { | ||
req, | ||
code: Server.errors.BAD_REQUEST, | ||
message: Server.errorMessages[Server.errors.BAD_REQUEST], | ||
context: { | ||
name: "TRANSPORT_HANDSHAKE_ERROR", | ||
error: e | ||
} | ||
}); | ||
sendErrorMessage(req, req.res, Server.errors.BAD_REQUEST); | ||
@@ -281,14 +356,17 @@ return; | ||
const socket = new Socket(id, this, transport, req, protocol); | ||
const self = this; | ||
if (this.opts.cookie) { | ||
transport.on("headers", headers => { | ||
headers["Set-Cookie"] = cookieMod.serialize( | ||
this.opts.cookie.name, | ||
id, | ||
this.opts.cookie | ||
); | ||
}); | ||
} | ||
transport.on("headers", (headers, req) => { | ||
const isInitialRequest = !req._query.sid; | ||
if (isInitialRequest) { | ||
if (this.opts.cookie) { | ||
headers["Set-Cookie"] = [ | ||
cookieMod.serialize(this.opts.cookie.name, id, this.opts.cookie) | ||
]; | ||
} | ||
this.emit("initial_headers", headers, req); | ||
} | ||
this.emit("headers", headers, req); | ||
}); | ||
transport.onRequest(req); | ||
@@ -299,5 +377,5 @@ | ||
socket.once("close", function() { | ||
delete self.clients[id]; | ||
self.clientsCount--; | ||
socket.once("close", () => { | ||
delete this.clients[id]; | ||
this.clientsCount--; | ||
}); | ||
@@ -316,6 +394,11 @@ | ||
const self = this; | ||
this.verify(req, true, function(err, success) { | ||
if (!success) { | ||
abortConnection(socket, err); | ||
this.verify(req, true, (errorCode, errorContext) => { | ||
if (errorCode) { | ||
this.emit("connection_error", { | ||
req, | ||
code: errorCode, | ||
message: Server.errorMessages[errorCode], | ||
context: errorContext | ||
}); | ||
abortConnection(socket, errorCode, errorContext); | ||
return; | ||
@@ -328,4 +411,4 @@ } | ||
// delegate to ws | ||
self.ws.handleUpgrade(req, socket, head, function(conn) { | ||
self.onWebSocket(req, conn); | ||
this.ws.handleUpgrade(req, socket, head, conn => { | ||
this.onWebSocket(req, conn); | ||
}); | ||
@@ -405,5 +488,3 @@ }); | ||
*/ | ||
attach(server, options) { | ||
const self = this; | ||
options = options || {}; | ||
attach(server, options = {}) { | ||
let path = (options.path || "/engine.io").replace(/\/$/, ""); | ||
@@ -423,10 +504,10 @@ | ||
server.removeAllListeners("request"); | ||
server.on("close", self.close.bind(self)); | ||
server.on("listening", self.init.bind(self)); | ||
server.on("close", this.close.bind(this)); | ||
server.on("listening", this.init.bind(this)); | ||
// add request handler | ||
server.on("request", function(req, res) { | ||
server.on("request", (req, res) => { | ||
if (check(req)) { | ||
debug('intercepting request for path "%s"', path); | ||
self.handleRequest(req, res); | ||
this.handleRequest(req, res); | ||
} else { | ||
@@ -441,6 +522,6 @@ let i = 0; | ||
if (~self.opts.transports.indexOf("websocket")) { | ||
server.on("upgrade", function(req, socket, head) { | ||
if (~this.opts.transports.indexOf("websocket")) { | ||
server.on("upgrade", (req, socket, head) => { | ||
if (check(req)) { | ||
self.handleUpgrade(req, socket, head); | ||
this.handleUpgrade(req, socket, head); | ||
} else if (false !== options.destroyUpgrade) { | ||
@@ -487,30 +568,24 @@ // default node behavior is to disconnect when no handlers | ||
* | ||
* @param {http.ServerResponse} response | ||
* @param {code} error code | ||
* @param req - the request object | ||
* @param res - the response object | ||
* @param errorCode - the error code | ||
* @param errorContext - additional error context | ||
* | ||
* @api private | ||
*/ | ||
function sendErrorMessage(req, res, code) { | ||
const headers = { "Content-Type": "application/json" }; | ||
function sendErrorMessage(req, res, errorCode, errorContext) { | ||
const statusCode = errorCode === Server.errors.FORBIDDEN ? 403 : 400; | ||
const message = | ||
errorContext && errorContext.message | ||
? errorContext.message | ||
: Server.errorMessages[errorCode]; | ||
const isForbidden = !Server.errorMessages.hasOwnProperty(code); | ||
if (isForbidden) { | ||
res.writeHead(403, headers); | ||
res.end( | ||
JSON.stringify({ | ||
code: Server.errors.FORBIDDEN, | ||
message: code || Server.errorMessages[Server.errors.FORBIDDEN] | ||
}) | ||
); | ||
return; | ||
} | ||
if (res !== undefined) { | ||
res.writeHead(400, headers); | ||
res.end( | ||
JSON.stringify({ | ||
code: code, | ||
message: Server.errorMessages[code] | ||
}) | ||
); | ||
} | ||
res.writeHead(statusCode, { "Content-Type": "application/json" }); | ||
res.end( | ||
JSON.stringify({ | ||
code: errorCode, | ||
message | ||
}) | ||
); | ||
} | ||
@@ -522,7 +597,9 @@ | ||
* @param {net.Socket} socket | ||
* @param {code} error code | ||
* @param {string} errorCode - the error code | ||
* @param {object} errorContext - additional error context | ||
* | ||
* @api private | ||
*/ | ||
function abortConnection(socket, code) { | ||
function abortConnection(socket, errorCode, errorContext) { | ||
socket.on("error", () => { | ||
@@ -532,5 +609,3 @@ debug("ignoring error from closed connection"); | ||
if (socket.writable) { | ||
const message = Server.errorMessages.hasOwnProperty(code) | ||
? Server.errorMessages[code] | ||
: String(code || ""); | ||
const message = errorContext.message || Server.errorMessages[errorCode]; | ||
const length = Buffer.byteLength(message); | ||
@@ -537,0 +612,0 @@ socket.write( |
@@ -84,45 +84,44 @@ const EventEmitter = require("events"); | ||
onPacket(packet) { | ||
if ("open" === this.readyState) { | ||
// export packet event | ||
debug("packet"); | ||
this.emit("packet", packet); | ||
if ("open" !== this.readyState) { | ||
return debug("packet received with closed socket"); | ||
} | ||
// export packet event | ||
debug(`received packet ${packet.type}`); | ||
this.emit("packet", packet); | ||
// Reset ping timeout on any packet, incoming data is a good sign of | ||
// other side's liveness | ||
this.resetPingTimeout( | ||
this.server.opts.pingInterval + this.server.opts.pingTimeout | ||
); | ||
// Reset ping timeout on any packet, incoming data is a good sign of | ||
// other side's liveness | ||
this.resetPingTimeout( | ||
this.server.opts.pingInterval + this.server.opts.pingTimeout | ||
); | ||
switch (packet.type) { | ||
case "ping": | ||
if (this.transport.protocol !== 3) { | ||
this.onError("invalid heartbeat direction"); | ||
return; | ||
} | ||
debug("got ping"); | ||
this.sendPacket("pong"); | ||
this.emit("heartbeat"); | ||
break; | ||
switch (packet.type) { | ||
case "ping": | ||
if (this.transport.protocol !== 3) { | ||
this.onError("invalid heartbeat direction"); | ||
return; | ||
} | ||
debug("got ping"); | ||
this.sendPacket("pong"); | ||
this.emit("heartbeat"); | ||
break; | ||
case "pong": | ||
if (this.transport.protocol === 3) { | ||
this.onError("invalid heartbeat direction"); | ||
return; | ||
} | ||
debug("got pong"); | ||
this.schedulePing(); | ||
this.emit("heartbeat"); | ||
break; | ||
case "pong": | ||
if (this.transport.protocol === 3) { | ||
this.onError("invalid heartbeat direction"); | ||
return; | ||
} | ||
debug("got pong"); | ||
this.schedulePing(); | ||
this.emit("heartbeat"); | ||
break; | ||
case "error": | ||
this.onClose("parse error"); | ||
break; | ||
case "error": | ||
this.onClose("parse error"); | ||
break; | ||
case "message": | ||
this.emit("data", packet.data); | ||
this.emit("message", packet.data); | ||
break; | ||
} | ||
} else { | ||
debug("packet received with closed socket"); | ||
case "message": | ||
this.emit("data", packet.data); | ||
this.emit("message", packet.data); | ||
break; | ||
} | ||
@@ -216,6 +215,4 @@ } | ||
const self = this; | ||
// set transport upgrade timer | ||
self.upgradeTimeoutTimer = setTimeout(function() { | ||
this.upgradeTimeoutTimer = setTimeout(() => { | ||
debug("client did not complete upgrade - closing transport"); | ||
@@ -228,20 +225,20 @@ cleanup(); | ||
function onPacket(packet) { | ||
const onPacket = packet => { | ||
if ("ping" === packet.type && "probe" === packet.data) { | ||
transport.send([{ type: "pong", data: "probe" }]); | ||
self.emit("upgrading", transport); | ||
clearInterval(self.checkIntervalTimer); | ||
self.checkIntervalTimer = setInterval(check, 100); | ||
} else if ("upgrade" === packet.type && self.readyState !== "closed") { | ||
this.emit("upgrading", transport); | ||
clearInterval(this.checkIntervalTimer); | ||
this.checkIntervalTimer = setInterval(check, 100); | ||
} else if ("upgrade" === packet.type && this.readyState !== "closed") { | ||
debug("got upgrade packet - upgrading"); | ||
cleanup(); | ||
self.transport.discard(); | ||
self.upgraded = true; | ||
self.clearTransport(); | ||
self.setTransport(transport); | ||
self.emit("upgrade", transport); | ||
self.flush(); | ||
if (self.readyState === "closing") { | ||
transport.close(function() { | ||
self.onClose("forced close"); | ||
this.transport.discard(); | ||
this.upgraded = true; | ||
this.clearTransport(); | ||
this.setTransport(transport); | ||
this.emit("upgrade", transport); | ||
this.flush(); | ||
if (this.readyState === "closing") { | ||
transport.close(() => { | ||
this.onClose("forced close"); | ||
}); | ||
@@ -253,20 +250,20 @@ } | ||
} | ||
} | ||
}; | ||
// we force a polling cycle to ensure a fast upgrade | ||
function check() { | ||
if ("polling" === self.transport.name && self.transport.writable) { | ||
const check = () => { | ||
if ("polling" === this.transport.name && this.transport.writable) { | ||
debug("writing a noop packet to polling for fast upgrade"); | ||
self.transport.send([{ type: "noop" }]); | ||
this.transport.send([{ type: "noop" }]); | ||
} | ||
} | ||
}; | ||
function cleanup() { | ||
self.upgrading = false; | ||
const cleanup = () => { | ||
this.upgrading = false; | ||
clearInterval(self.checkIntervalTimer); | ||
self.checkIntervalTimer = null; | ||
clearInterval(this.checkIntervalTimer); | ||
this.checkIntervalTimer = null; | ||
clearTimeout(self.upgradeTimeoutTimer); | ||
self.upgradeTimeoutTimer = null; | ||
clearTimeout(this.upgradeTimeoutTimer); | ||
this.upgradeTimeoutTimer = null; | ||
@@ -276,6 +273,6 @@ transport.removeListener("packet", onPacket); | ||
transport.removeListener("error", onError); | ||
self.removeListener("close", onClose); | ||
} | ||
this.removeListener("close", onClose); | ||
}; | ||
function onError(err) { | ||
const onError = err => { | ||
debug("client did not complete upgrade - %s", err); | ||
@@ -285,11 +282,11 @@ cleanup(); | ||
transport = null; | ||
} | ||
}; | ||
function onTransportClose() { | ||
const onTransportClose = () => { | ||
onError("transport closed"); | ||
} | ||
}; | ||
function onClose() { | ||
const onClose = () => { | ||
onError("socket closed"); | ||
} | ||
}; | ||
@@ -300,3 +297,3 @@ transport.on("packet", onPacket); | ||
self.once("close", onClose); | ||
this.once("close", onClose); | ||
} | ||
@@ -346,7 +343,6 @@ | ||
clearTimeout(this.upgradeTimeoutTimer); | ||
const self = this; | ||
// clean writeBuffer in next tick, so developers can still | ||
// grab the writeBuffer on 'close' event | ||
process.nextTick(function() { | ||
self.writeBuffer = []; | ||
process.nextTick(() => { | ||
this.writeBuffer = []; | ||
}); | ||
@@ -366,16 +362,9 @@ this.packetsFn = []; | ||
setupSendCallback() { | ||
const self = this; | ||
this.transport.on("drain", onDrain); | ||
this.cleanupFn.push(function() { | ||
self.transport.removeListener("drain", onDrain); | ||
}); | ||
// the message was sent successfully, execute the callback | ||
function onDrain() { | ||
if (self.sentCallbackFn.length > 0) { | ||
const seqFn = self.sentCallbackFn.splice(0, 1)[0]; | ||
const onDrain = () => { | ||
if (this.sentCallbackFn.length > 0) { | ||
const seqFn = this.sentCallbackFn.splice(0, 1)[0]; | ||
if ("function" === typeof seqFn) { | ||
debug("executing send callback"); | ||
seqFn(self.transport); | ||
seqFn(this.transport); | ||
} else if (Array.isArray(seqFn)) { | ||
@@ -387,3 +376,3 @@ debug("executing batch send callback"); | ||
if ("function" === typeof seqFn[i]) { | ||
seqFn[i](self.transport); | ||
seqFn[i](this.transport); | ||
} | ||
@@ -393,3 +382,9 @@ } | ||
} | ||
} | ||
}; | ||
this.transport.on("drain", onDrain); | ||
this.cleanupFn.push(() => { | ||
this.transport.removeListener("drain", onDrain); | ||
}); | ||
} | ||
@@ -396,0 +391,0 @@ |
@@ -73,12 +73,10 @@ const Transport = require("../transport"); | ||
const self = this; | ||
const onClose = () => { | ||
this.onError("poll connection closed prematurely"); | ||
}; | ||
function onClose() { | ||
self.onError("poll connection closed prematurely"); | ||
} | ||
function cleanup() { | ||
const cleanup = () => { | ||
req.removeListener("close", onClose); | ||
self.req = self.res = null; | ||
} | ||
this.req = this.res = null; | ||
}; | ||
@@ -122,17 +120,16 @@ req.cleanup = cleanup; | ||
let chunks = isBinary ? Buffer.concat([]) : ""; | ||
const self = this; | ||
function cleanup() { | ||
const cleanup = () => { | ||
req.removeListener("data", onData); | ||
req.removeListener("end", onEnd); | ||
req.removeListener("close", onClose); | ||
self.dataReq = self.dataRes = chunks = null; | ||
} | ||
this.dataReq = this.dataRes = chunks = null; | ||
}; | ||
function onClose() { | ||
const onClose = () => { | ||
cleanup(); | ||
self.onError("data request connection closed prematurely"); | ||
} | ||
this.onError("data request connection closed prematurely"); | ||
}; | ||
function onData(data) { | ||
const onData = data => { | ||
let contentLength; | ||
@@ -147,10 +144,10 @@ if (isBinary) { | ||
if (contentLength > self.maxHttpBufferSize) { | ||
if (contentLength > this.maxHttpBufferSize) { | ||
chunks = isBinary ? Buffer.concat([]) : ""; | ||
req.connection.destroy(); | ||
} | ||
} | ||
}; | ||
function onEnd() { | ||
self.onData(chunks); | ||
const onEnd = () => { | ||
this.onData(chunks); | ||
@@ -164,6 +161,6 @@ const headers = { | ||
res.writeHead(200, self.headers(req, headers)); | ||
res.writeHead(200, this.headers(req, headers)); | ||
res.end("ok"); | ||
cleanup(); | ||
} | ||
}; | ||
@@ -184,11 +181,10 @@ req.on("close", onClose); | ||
debug('received "%s"', data); | ||
const self = this; | ||
const callback = function(packet) { | ||
const callback = packet => { | ||
if ("close" === packet.type) { | ||
debug("got xhr close packet"); | ||
self.onClose(); | ||
this.onClose(); | ||
return false; | ||
} | ||
self.onPacket(packet); | ||
this.onPacket(packet); | ||
}; | ||
@@ -255,5 +251,4 @@ | ||
debug('writing "%s"', data); | ||
const self = this; | ||
this.doWrite(data, options, function() { | ||
self.req.cleanup(); | ||
this.doWrite(data, options, () => { | ||
this.req.cleanup(); | ||
}); | ||
@@ -268,4 +263,2 @@ } | ||
doWrite(data, options, callback) { | ||
const self = this; | ||
// explicit UTF-8 is required for pages not served under utf | ||
@@ -281,2 +274,10 @@ const isString = typeof data === "string"; | ||
const respond = data => { | ||
headers["Content-Length"] = | ||
"string" === typeof data ? Buffer.byteLength(data) : data.length; | ||
this.res.writeHead(200, this.headers(this.req, headers)); | ||
this.res.end(data); | ||
callback(); | ||
}; | ||
if (!this.httpCompression || !options.compress) { | ||
@@ -299,6 +300,6 @@ respond(data); | ||
this.compress(data, encoding, function(err, data) { | ||
this.compress(data, encoding, (err, data) => { | ||
if (err) { | ||
self.res.writeHead(500); | ||
self.res.end(); | ||
this.res.writeHead(500); | ||
this.res.end(); | ||
callback(err); | ||
@@ -311,10 +312,2 @@ return; | ||
}); | ||
function respond(data) { | ||
headers["Content-Length"] = | ||
"string" === typeof data ? Buffer.byteLength(data) : data.length; | ||
self.res.writeHead(200, self.headers(self.req, headers)); | ||
self.res.end(data); | ||
callback(); | ||
} | ||
} | ||
@@ -353,3 +346,2 @@ | ||
const self = this; | ||
let closeTimeoutTimer; | ||
@@ -362,2 +354,8 @@ | ||
const onClose = () => { | ||
clearTimeout(closeTimeoutTimer); | ||
fn(); | ||
this.onClose(); | ||
}; | ||
if (this.writable) { | ||
@@ -375,8 +373,2 @@ debug("transport writable - closing right away"); | ||
} | ||
function onClose() { | ||
clearTimeout(closeTimeoutTimer); | ||
fn(); | ||
self.onClose(); | ||
} | ||
} | ||
@@ -401,3 +393,3 @@ | ||
this.emit("headers", headers); | ||
this.emit("headers", headers, req); | ||
return headers; | ||
@@ -404,0 +396,0 @@ } |
@@ -17,5 +17,2 @@ const Transport = require("../transport"); | ||
this.socket.on("error", this.onError.bind(this)); | ||
this.socket.on("headers", headers => { | ||
this.emit("headers", headers); | ||
}); | ||
this.writable = true; | ||
@@ -70,34 +67,36 @@ this.perMessageDeflate = null; | ||
send(packets) { | ||
var self = this; | ||
const packet = packets.shift(); | ||
if (typeof packet === "undefined") { | ||
this.writable = true; | ||
this.emit("drain"); | ||
return; | ||
} | ||
for (var i = 0; i < packets.length; i++) { | ||
var packet = packets[i]; | ||
this.parser.encodePacket(packet, self.supportsBinary, send); | ||
// always creates a new object since ws modifies it | ||
const opts = {}; | ||
if (packet.options) { | ||
opts.compress = packet.options.compress; | ||
} | ||
function send(data) { | ||
debug('writing "%s"', data); | ||
// always creates a new object since ws modifies it | ||
var opts = {}; | ||
if (packet.options) { | ||
opts.compress = packet.options.compress; | ||
} | ||
if (self.perMessageDeflate) { | ||
var len = | ||
const send = data => { | ||
if (this.perMessageDeflate) { | ||
const len = | ||
"string" === typeof data ? Buffer.byteLength(data) : data.length; | ||
if (len < self.perMessageDeflate.threshold) { | ||
if (len < this.perMessageDeflate.threshold) { | ||
opts.compress = false; | ||
} | ||
} | ||
debug('writing "%s"', data); | ||
this.writable = false; | ||
self.writable = false; | ||
self.socket.send(data, opts, onEnd); | ||
} | ||
this.socket.send(data, opts, err => { | ||
if (err) return this.onError("write error", err.stack); | ||
this.send(packets); | ||
}); | ||
}; | ||
function onEnd(err) { | ||
if (err) return self.onError("write error", err.stack); | ||
self.writable = true; | ||
self.emit("drain"); | ||
if (packet.options && typeof packet.options.wsPreEncoded === "string") { | ||
send(packet.options.wsPreEncoded); | ||
} else { | ||
this.parser.encodePacket(packet, this.supportsBinary, send); | ||
} | ||
@@ -104,0 +103,0 @@ } |
{ | ||
"name": "engine.io", | ||
"version": "5.0.0", | ||
"version": "5.1.0", | ||
"description": "The realtime engine behind Socket.IO. Provides the foundation of a bidirectional connection between client and server", | ||
@@ -39,3 +39,3 @@ "main": "lib/engine.io.js", | ||
"eiows": "^3.3.0", | ||
"engine.io-client": "5.0.0", | ||
"engine.io-client": "5.1.0", | ||
"engine.io-client-v3": "npm:engine.io-client@3.5.0", | ||
@@ -42,0 +42,0 @@ "eslint": "^4.19.1", |
@@ -208,2 +208,33 @@ | ||
- `initial_headers` | ||
- Fired on the first request of the connection, before writing the response headers | ||
- **Arguments** | ||
- `headers` (`Object`): a hash of headers | ||
- `req` (`http.IncomingMessage`): the request | ||
- `headers` | ||
- Fired on the all requests of the connection, before writing the response headers | ||
- **Arguments** | ||
- `headers` (`Object`): a hash of headers | ||
- `req` (`http.IncomingMessage`): the request | ||
- `connection_error` | ||
- Fired when an error occurs when establishing the connection. | ||
- **Arguments** | ||
- `error`: an object with following properties: | ||
- `req` (`http.IncomingMessage`): the request that was dropped | ||
- `code` (`Number`): one of `Server.errors` | ||
- `message` (`string`): one of `Server.errorMessages` | ||
- `context` (`Object`): extra info about the error | ||
| Code | Message | | ||
| ---- | ------- | | ||
| 0 | "Transport unknown" | ||
| 1 | "Session ID unknown" | ||
| 2 | "Bad handshake method" | ||
| 3 | "Bad request" | ||
| 4 | "Forbidden" | ||
| 5 | "Unsupported protocol version" | ||
##### Properties | ||
@@ -210,0 +241,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
98639
2339
595