Open songinnight opened 2 months ago
@sequencerr Thanks for the answer. But, unfortunately, it works in Node.js but not in Bun. I'm having a weird behavior.
I've tried it on Bun 1.1.26
and 1.1.27-canary
import tls from 'tls';
tls.DEFAULT_MAX_VERSION = 'TLSv1.2'; // <-- This solves the problem only on Node.js
const wsUrl = `wss://live.fantasysportnetwork.com/public/lobby/socket/v2/r6c3i3wejv3qyqc7?messageFormat=json&device=Desktop&instance=uh2kmg-r6c3i3wejv3qyqc7-&EVOSESSIONID=r6c3i3wejv3qyqc7sg2abheehedelugl97355fc628031ff7877c2d1b4065355cc43ced0edceda0af&client_version=6.20240830.72721.44127-54f6972596`;
const startTime = Date.now();
const ws = new WebSocket(wsUrl, {
// rejectUnauthorized: false,
// perMessageDeflate: false,
// handshakeTimeout: 15000,
// enableTrace: true,
tlsOptions: { // <-- It doesn't work on both Node.js and Bun
maxVersion: "TLSv1.2",
},
tls: { // <-- It doesn't work on both Node.js and Bun
maxVersion: "TLSv1.2",
}
});
console.log(`▶ --- START WEBSOCKET CONNECTION ---`);
ws.addEventListener('open', async (event) => {
// Cannot reach here or it takes about 10 seconds with Bun and Node.js(TLSv1.3)
console.log(`▶ GOOD! WS OPENED (${Date.now() - startTime}ms)`);
});
ws.addEventListener('message', (event) => {
console.log(`▶ MESSAGE: ${event.data} (${Date.now() - startTime}ms)`);
ws.close();
});
ws.addEventListener('close', event => {
console.log(`▶ WS CLOSED (${Date.now() - startTime}ms)`);
});
ws.addEventListener('error', event => {
console.log(`▶ WS ERROR (${Date.now() - startTime}ms)`, event);
});
bun-debug.exe
...
[alloc] new(src.http.websocket_http_client.NewHTTPUpgradeClient(true)) = src.http.websocket_http_client.NewHTTPUpgradeClient(true)@5e784541c00
[uws] connect(live.fantasysportnetwork.com, 443)
[alloc] new(Request) = src.bun.js.api.bun.dns_resolver.InternalDNS.Request@5e784340120
▶ --- START WEBSOCKET CONNECTION ---
[WebSocketClient] onOpen
[uws] us_socket_write(*src.deps.boringssl.translated.SSL@23ccc7253d8, 417) = 0
[WebSocketClient] onHandshake A (1)
[EventLoop] enter() = 0
[EventLoop] exit() = 0
[uws] us_socket_write(*src.deps.boringssl.translated.SSL@23ccc7253d8, 417) = 417
(It's stuck here for about 10 seconds.)
nodejs doesn't have builtin WebSocket. WebSocket package does not have tlsOptions, tls options entries.
you want provide same https options to server
options entry https://github.com/websockets/ws/blob/master/examples/ssl.js
Node.js >= v21 has a built-in websocket client.
https://nodejs.org/en/blog/announcements/v21-release-announce
I want to develop a project with Bun. If this not solved, I have to change the entire project code back to Node.js 😱
I've also tried the ws
package, but it uses Bun's WebSockets internally, so I don't think that will solve the problem.
I've lost almost a week of sleep over this issue.
then use bun's websocket api
As I mentioned above Bun does not have TLS v1.2 limitation option like Node.js
https://github.com/oven-sh/bun/issues/13710#issuecomment-2327045191
Please, refer to my reproducing code.
And there's no guarantee that using TLS v1.2 in Bun will solve the underlying problem. 😢
There seems to be some confusion. This is a feature in Node.js (both the CLI flag and API option) It does not exist (yet) in Bun.
for ws client with tls options you want to use ws package with custom agent
you didn't mention about underlying problem
yeah and issue should be called something like
support for tls nodejs cli flags in bun
for ws client with tls options you want to use ws package with custom agent
did you figure it out? try this:
import { Agent } from 'https';
import WebSocket from 'ws';
const ws = new WebSocket('wss://yourserver.example.com', {
agent: new Agent({
minVersion: 'TLSv1.2',
maxVersion: 'TLSv1.2'
}),
});
I tried many ways before including ws
agent handler.
However, it doesn't seem to be involved in uws
TLS handshaking.
a.mjs
import { Agent } from 'node:https';
import WebSocket from 'ws';
const wsUrl = `wss://live.fantasysportnetwork.com/public/lobby/socket/v2/r6c3i3wejv3qyqc7?messageFormat=json&device=Desktop&instance=uh2kmg-r6c3i3wejv3qyqc7-&EVOSESSIONID=r6c3i3wejv3qyqc7sg2abheehedelugl97355fc628031ff7877c2d1b4065355cc43ced0edceda0af&client_version=6.20240830.72721.44127-54f6972596`;
const startTime = Date.now();
const ws = new WebSocket(wsUrl, {
agent: new Agent({ // <-- Not working on Bun. It's hang on uWS level
maxVersion: 'TLSv1.2',
}),
});
console.log(`▶ --- START WEBSOCKET CONNECTION (using agent) ---`);
ws.addEventListener('open', async (event) => {
// Cannot reach here or it takes about 10 seconds on Bun
console.log(`▶ WS OPENED (${Date.now() - startTime}ms)`);
});
ws.addEventListener('message', (event) => {
console.log(`▶ MESSAGE: ${event.data} (${Date.now() - startTime}ms)`);
ws.close();
});
ws.addEventListener('close', event => {
console.log(`▶ WS CLOSED (${Date.now() - startTime}ms)`);
});
ws.addEventListener('error', event => {
console.log(`\n▶▶▶ WS ERROR ${Date.now() - startTime}ms`, event);
});
bun-debug.exe a.mjs
Output Log...
[alloc] new(src.http.websocket_http_client.NewHTTPUpgradeClient(true)) = src.http.websocket_http_client.NewHTTPUpgradeClient(true)@3d8b4431800
[uws] connect(live.fantasysportnetwork.com, 443)
[alloc] new(Request) = src.bun.js.api.bun.dns_resolver.InternalDNS.Request@3d8b4340080
▶ --- START WEBSOCKET CONNECTION (using agent) ---
[WebSocketClient] onOpen
[uws] us_socket_write(*src.deps.boringssl.translated.SSL@1fe667d5788, 417) = 0
[WebSocketClient] onHandshake A (1)
[EventLoop] enter() = 0
[EventLoop] exit() = 0
[uws] us_socket_write(*src.deps.boringssl.translated.SSL@1fe667d5788, 417) = 417
(...no websocket upgrade response from the server for about 10 seconds)
[WebSocketClient] onData
[WebSocketClient] onDidConnect
[EventLoop] enter() = 0
[alloc] new(src.http.websocket_http_client.NewWebSocketClient(true)) = src.http.websocket_http_client.NewWebSocketClient(true)@3d8b4390180
▶ WS OPENED (9941ms)
[EventLoop] exit() = 0
[WebSocketClient] onData (need_header)
[WebSocketClient] onData (need_body)
[EventLoop] enter() = 0
▶ MESSAGE: {"type":"connection.kickout","args":{"reason":"inactivity"}} (9942ms)
[WebSocketClient] Sending close with code 1000
[uws] us_socket_write(*src.deps.boringssl.translated.SSL@1fe667d5788, 8) = 8
[EventLoop] enter() = 1
▶ WS CLOSED (9942ms)
[EventLoop] exit() = 1
[WebSocketClient] clearData
[EventLoop] exit() = 0
[WebSocketClient] onClose
[WebSocketClient] clearData
node a.mjs
Output Log▶ --- START WEBSOCKET CONNECTION (using agent) ---
▶ WS OPENED (1159ms) <---- in node.js agent works as expected
▶ MESSAGE: {"type":"connection.kickout","args":{"reason":"inactivity"}} (1160ms)
▶ WS CLOSED (1169ms)
The weird thing is that the browser has no issues with TLS 1.3. It's responding without a long delay. I really don't know why.
Currently in Bun we did not implement the options of minVersion
and maxVersion
on net
, tls
, http
or https
modules yet, but we plan to add these options since we wanna to increase node.js compatibility.
Well sure compatibility is less prioritized then native bun implementations. But I guess we should figure out what broking stability there and causes delays in tls v1.3 first.
p.s. because I also had problems with tls and fetch api in nodejs but in bun it just automatically puts right version without configs.
I've found out the underlying problem.
It was related to cipher
.
(It seems to only happen on certain server)
In node.js
with ws
package I resolved the 10sec delay and no upgrade response problem.
// Node.js
import { WebSocket as WS } from 'ws';
const CIPHERS = [
// for TLS v1.3
'TLS_AES_256_GCM_SHA384',
'TLS_CHACHA20_POLY1305_SHA256 ',
'TLS_AES_128_GCM_SHA256',
'TLS_AES_128_CCM_8_SHA256',
];
const ws = new WS(url, {
// enableTrace: true,
ciphers: CIPHERS.join(':'),
});
ws.on('upgrade', res => {
// OK !
console.log(res?.headers?.['set-cookie']);
});
...
Unfortunately, Bun
doesn't support http's request.on('upgrade', (res) => {...})
event.
So we can't use the ws
.
In addition, I need the response header data on upgrade to get set-cookie
.
(Bun
's builtin WebSocket
doesn't support the ciphers parameter yet)
These are critical for us. so, I have to go back to node.js
.
😂
What is the problem this feature would solve?
Currently, my project is experiencing a delay of 8 to 10 seconds in receiving network(client) responses from certain server.
(Perhaps the target server is using Akamai and has some additional security settings in place to prevent non-browser http and websocket clients.)In node.js, the
--tls-max-v1.2
option solved the problem, but I haven't found a way to limit the TLS version to1.2
in Bun yet.What is the feature you are proposing to solve the problem?
would be nice something like this.
bun --tls-max-v1.2
process.env.BUN_TLS_MAX_VERSION = '1.2'
What alternatives have you considered?
No response