helidon-io / helidon

Java libraries for writing microservices
https://helidon.io
Apache License 2.0
3.45k stars 563 forks source link

WebSocket upgrade request missing the Connection header #8189

Closed 4e6 closed 6 months ago

4e6 commented 6 months ago

Environment Details


Problem Description

When trying to create a WebSocket connection with WsClient, it fails to upgrade the connection

Exception in thread "main" io.helidon.webclient.websocket.WsClientException: Failed to upgrade to WebSocket. Response: 200 OK: Via: 1.1 fly.io
Content-Length: 630
Content-Type: text/plain
Date: Wed, 03 Jan 2024 19:57:01 GMT
Server: Fly/ec8196c09 (2024-01-02)
fly-request-id: 01HK8ED5H2PDAM0NC27TD3ZGQD-lhr

    at io.helidon.webclient.websocket@4.0.2/io.helicon.webclient.websocket.WsClientImpl.connect(WsClientImpl.java:123)

According to the Mozilla doc, a WebSocket upgrade request should contain two headers:

Connection: Upgrade
Upgrade: websocket

Debugging showed that the upgrade request sets the Upgrade header but is missing the Connection one https://github.com/helidon-io/helidon/blob/68de0bb538483c5f76fdf78c686e273f15b4c684/webclient/http1/src/main/java/io/helidon/webclient/http1/Http1ClientRequestImpl.java#L130-L133

After setting the Connection header (see the example below), the connection was successfully established.

Steps to reproduce

This example results in an io.helidon.webclient.websocket.WsClientException: Failed to upgrade to WebSocket.

io.helidon.webclient.websocket.WsClient.builder()
    .build()
    .connect(
        new java.net.URI("wss://echo.websocket.org/"), 
        new io.helidon.websocket.WsListener() {}
    );

After adding a Connection header, the connection is established successfully

var headersMap = new java.util.HashMap<String, String>();
headersMap.put("CONNECTION", "Upgrade");
io.helidon.webclient.websocket.WsClient.builder()
    .defaultHeadersMap(headersMap)
    .build()
    .connect(
        new java.net.URI("wss://echo.websocket.org/"), 
        new io.helidon.websocket.WsListener() {}
    );
spericas commented 6 months ago

@4e6 Thanks for the report, yes it looks like that header is missing. Just to fully understand your scenario, you are using Helidon as a client of some third-party WS server right?

4e6 commented 6 months ago

Yes, I would like to establish a connection with the Yjs server yjs/y-websocket.