diff --git a/index.js b/index.js index c3e64b2..0038233 100644 --- a/index.js +++ b/index.js @@ -97,13 +97,11 @@ const setupMaster = (httpServer, opts) => { return; } workerId = computeWorkerId(data); - const mayHaveMultipleChunks = !( - data.startsWith("GET") || - data - .substring(0, data.indexOf("\r\n\r\n")) - .includes("pgrade: websocket") - ); - socket.pause(); + + const head = data.substring(0, data.indexOf("\r\n\r\n")).toLowerCase(); + const mayHaveMultipleChunks = + head.includes("content-length:") || head.includes("transfer-encoding:"); + if (mayHaveMultipleChunks) { connectionId = randomId(); } diff --git a/test/fixtures/cors.js b/test/fixtures/cors.js new file mode 100644 index 0000000..1ee7a10 --- /dev/null +++ b/test/fixtures/cors.js @@ -0,0 +1,71 @@ +const cluster = require("cluster"); +const { createServer, request } = require("http"); +const { Server } = require("socket.io"); +const { setupMaster, setupWorker } = require("../.."); +const assert = require("assert").strict; + +if (cluster.isWorker) { + const httpServer = createServer(); + const io = new Server(httpServer, { + cors: { + origin: true, + }, + }); + setupWorker(io); + + io.on("connection", (socket) => { + socket.on("foo", (val) => { + socket.emit("bar", val); + }); + }); + + return; +} + +const WORKER_COUNT = 3; + +for (let i = 0; i < WORKER_COUNT; i++) { + cluster.fork(); +} + +const httpServer = createServer(); + +setupMaster(httpServer, { + loadBalancingMethod: process.env.LB_METHOD || "least-connection", +}); + +const waitFor = (emitter, event) => { + return new Promise((resolve) => { + emitter.once(event, resolve); + }); +}; + +httpServer.listen(async () => { + const port = httpServer.address().port; + + const res = await sendRequest({ + port, + method: "options", + path: "/socket.io/", + headers: { + origin: "https://example.com", + }, + }); + + assert.equal(res.statusCode, 204); + + assert.equal( + res.headers["access-control-allow-origin"], + "https://example.com" + ); + + // cleanup + for (const id in cluster.workers) { + cluster.workers[id].kill(); + } + httpServer.close(); +}); + +function sendRequest(options) { + return new Promise((resolve) => request(options, resolve).end()); +} diff --git a/test/index.js b/test/index.js index ed4dc7c..b482d95 100644 --- a/test/index.js +++ b/test/index.js @@ -43,8 +43,8 @@ describe("@socket.io/sticky", () => { exec(fixture("connection.js"), { env: { TRANSPORT: "polling" } }, done); }); - it("should work with HTTP long-polling only", (done) => { - exec(fixture("connection.js"), { env: { TRANSPORT: "polling" } }, done); + it("should work with CORS", (done) => { + exec(fixture("cors.js"), done); }); it("should return a 503 error when no worker is available (polling)", (done) => {