Open
Description
Describe the bug
Creating HTTP/2 server mentioned in the example works well with Firefox because Firefox still uses HTTP/1.1 to connect to web server. However, chrome has implemented CONNECT
method of HTTP/2, and thus socket.io no longer connects with HTTP/2 server.
Chrome 120 still connects Web Socket over HTTP 1.1, but this stops working from 121 onwards.
To Reproduce
- Juse use simple socket.io sample to create HTTP/2 server with SSL certificate.
- Try to connect to socket.io server from Google Chorme.
Expected behavior
It should connect to socket.io server, but it does not.
Platform:
- OS: Desktop
- Browser: Google Chorme (121.0.6167.161) +
Additional context
For HTTP/1.1 , http2Server emits upgrade
event, which engine.io handles correctly.
For HTTP/2, http2Server does not emit upgrade
event if web socket client sends HTTP-METHOD='CONNECT'
.
Work Around/Recommendation
httpServer.prependListener("stream", (stream, headers) => {
// we need to look for CONNECT
if(headers[":method"] !== "CONNECT") {
return;
}
try {
// this keeps socket alive...
stream.setTimeout(0);
(stream as any).setKeepAlive?.(true, 0);
(stream as any).setNoDelay = function() {
// this will keep the stream open
};
const websocket = new WebSocket(null, void 0, {
headers
});
websocket.setSocket(stream, Buffer.alloc(0), {
maxPayload: 104857600,
skipUTF8Validation: false,
});
const path = headers[":path"];
const url = new URL(path, "http://a");
const _query = {};
for (const [key, value] of url.searchParams.entries()) {
_query[key] = value;
}
// fake build request
const req = {
url: path,
headers,
websocket,
_query
};
stream.respond({
":status": 200
});
// for some reason this is not working !!
this.handshake("websocket",req,() => { try { stream.end(); } catch {} }).catch(console.error);
} catch (error) {
console.error(error);
}
});