Skip to content

Commit b624c50

Browse files
fix: add some randomness to the cache busting string generator
The yeast() method could generate the same string twice when used in two different iframes, which can cause Safari to only send one HTTP request (deduplication) and trigger an HTTP 400 error afterwards since the two iframes share the same session ID. This new method, combining 5 chars from the timestamp and 3 chars from Math.random() should be sufficient for our use case. Related: socketio/engine.io#690 See also: 874484c
1 parent c087dc5 commit b624c50

File tree

5 files changed

+25
-67
lines changed

5 files changed

+25
-67
lines changed

lib/contrib/yeast.ts

-62
This file was deleted.

lib/transports/polling.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { Transport } from "../transport.js";
2-
import { yeast } from "../contrib/yeast.js";
2+
import { randomString } from "../util.js";
33
import { encodePayload, decodePayload } from "engine.io-parser";
44
import debugModule from "debug"; // debug()
55

@@ -164,7 +164,7 @@ export abstract class Polling extends Transport {
164164

165165
// cache busting is forced
166166
if (false !== this.opts.timestampRequests) {
167-
query[this.opts.timestampParam] = yeast();
167+
query[this.opts.timestampParam] = randomString();
168168
}
169169

170170
if (!this.supportsBinary && !query.sid) {

lib/transports/websocket.ts

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { Transport } from "../transport.js";
2-
import { yeast } from "../contrib/yeast.js";
3-
import { pick } from "../util.js";
2+
import { pick, randomString } from "../util.js";
43
import { encodePacket } from "engine.io-parser";
54
import type { Packet, RawData } from "engine.io-parser";
65
import { globalThisShim as globalThis, nextTick } from "../globals.node.js";
@@ -140,7 +139,7 @@ export abstract class BaseWS extends Transport {
140139

141140
// append timestamp to URI
142141
if (this.opts.timestampRequests) {
143-
query[this.opts.timestampParam] = yeast();
142+
query[this.opts.timestampParam] = randomString();
144143
}
145144

146145
// communicate binary support capabilities

lib/util.ts

+10
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,13 @@ function utf8Length(str) {
5353
}
5454
return length;
5555
}
56+
57+
/**
58+
* Generates a random 8-characters string.
59+
*/
60+
export function randomString() {
61+
return (
62+
Date.now().toString(36).substring(3) +
63+
Math.random().toString(36).substring(2, 5)
64+
);
65+
}

test/engine.io-client.js

+11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
const expect = require("expect.js");
22
const { Socket, protocol } = require("..");
3+
const { randomString } = require("../build/cjs/util.js");
34

45
const expectedPort =
56
typeof location !== "undefined" && "https:" === location.protocol
@@ -99,4 +100,14 @@ describe("engine.io-client", () => {
99100
expect(client.hostname).to.be("::1");
100101
expect(client.port).to.be(expectedPort);
101102
});
103+
104+
it("should generate a random string", () => {
105+
const a = randomString();
106+
const b = randomString();
107+
const c = randomString();
108+
109+
expect(a.length).to.eql(8);
110+
expect(a).to.not.equal(b);
111+
expect(b).to.not.equal(c);
112+
});
102113
});

0 commit comments

Comments
 (0)