Skip to content

Commit ac7bb8e

Browse files
fix: properly detect requests without body
Related: socketio/socket.io#4786
1 parent e7f0375 commit ac7bb8e

File tree

3 files changed

+78
-9
lines changed

3 files changed

+78
-9
lines changed

index.js

+5-7
Original file line numberDiff line numberDiff line change
@@ -97,13 +97,11 @@ const setupMaster = (httpServer, opts) => {
9797
return;
9898
}
9999
workerId = computeWorkerId(data);
100-
const mayHaveMultipleChunks = !(
101-
data.startsWith("GET") ||
102-
data
103-
.substring(0, data.indexOf("\r\n\r\n"))
104-
.includes("pgrade: websocket")
105-
);
106-
socket.pause();
100+
101+
const head = data.substring(0, data.indexOf("\r\n\r\n")).toLowerCase();
102+
const mayHaveMultipleChunks =
103+
head.includes("content-length:") || head.includes("transfer-encoding:");
104+
107105
if (mayHaveMultipleChunks) {
108106
connectionId = randomId();
109107
}

test/fixtures/cors.js

+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
const cluster = require("cluster");
2+
const { createServer, request } = require("http");
3+
const { Server } = require("socket.io");
4+
const { setupMaster, setupWorker } = require("../..");
5+
const assert = require("assert").strict;
6+
7+
if (cluster.isWorker) {
8+
const httpServer = createServer();
9+
const io = new Server(httpServer, {
10+
cors: {
11+
origin: true,
12+
},
13+
});
14+
setupWorker(io);
15+
16+
io.on("connection", (socket) => {
17+
socket.on("foo", (val) => {
18+
socket.emit("bar", val);
19+
});
20+
});
21+
22+
return;
23+
}
24+
25+
const WORKER_COUNT = 3;
26+
27+
for (let i = 0; i < WORKER_COUNT; i++) {
28+
cluster.fork();
29+
}
30+
31+
const httpServer = createServer();
32+
33+
setupMaster(httpServer, {
34+
loadBalancingMethod: process.env.LB_METHOD || "least-connection",
35+
});
36+
37+
const waitFor = (emitter, event) => {
38+
return new Promise((resolve) => {
39+
emitter.once(event, resolve);
40+
});
41+
};
42+
43+
httpServer.listen(async () => {
44+
const port = httpServer.address().port;
45+
46+
const res = await sendRequest({
47+
port,
48+
method: "options",
49+
path: "/socket.io/",
50+
headers: {
51+
origin: "https://example.com",
52+
},
53+
});
54+
55+
assert.equal(res.statusCode, 204);
56+
57+
assert.equal(
58+
res.headers["access-control-allow-origin"],
59+
"https://example.com"
60+
);
61+
62+
// cleanup
63+
for (const id in cluster.workers) {
64+
cluster.workers[id].kill();
65+
}
66+
httpServer.close();
67+
});
68+
69+
function sendRequest(options) {
70+
return new Promise((resolve) => request(options, resolve).end());
71+
}

test/index.js

+2-2
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,8 @@ describe("@socket.io/sticky", () => {
4343
exec(fixture("connection.js"), { env: { TRANSPORT: "polling" } }, done);
4444
});
4545

46-
it("should work with HTTP long-polling only", (done) => {
47-
exec(fixture("connection.js"), { env: { TRANSPORT: "polling" } }, done);
46+
it("should work with CORS", (done) => {
47+
exec(fixture("cors.js"), done);
4848
});
4949

5050
it("should return a 503 error when no worker is available (polling)", (done) => {

0 commit comments

Comments
 (0)