Skip to content

HTTP/2 Web Socket in Chrome not working #5067

Open
@ackava

Description

@ackava

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

  1. Juse use simple socket.io sample to create HTTP/2 server with SSL certificate.
  2. 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);
  }
});

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingpackage:engine.ioThis concerns the "engine.io" package

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions