WebSockets header issue

Hi,

I do have a problem with WebSockets. That’s something completely new to me. I am naively trying to run:

ws.connect(
    'wss://url',
    {
        headers: {
            Pragma: "no-cache",
            Origin: "origin.com",
            "Accept-Encoding": "gzip, deflate, br",
            Host: "host.com",
            "Sec-WebSocket-Key": "KEY",
            Upgrade: "websocket",
            "Sec-WebSocket-Extensions": "permessage-deflate; client_max_window_bits",
            "Cache-Control": "no-cache",
            Connection: "Upgrade",
            "Sec-WebSocket-Version": "13"
        }
    },
    function (socket) {
        socket.on('open', () => console.log('connected'));
        socket.on('message', (data) => console.log('Message received: ', data));
        socket.on('close', () => console.log('disconnected'));
    }
);

But I am getting an error related to headers:

GoError: websocket: duplicate header not allowed: Sec-Websocket-Key
Run     at go.k6.io/k6/js/modules/k6/ws.(*WS).Connect-fm (native)

or

GoError: websocket: duplicate header not allowed: Connection
Run     at go.k6.io/k6/js/modules/k6/ws.(*WS).Connect-fm (native)

(duplicate header is random each time)
Is there a different way to define params or I am simply missing something?

Hi @Lidder,

A quick google search landed me at this issue. IN which they are talking about Sec-WebSocket-Extensions specifically and the fact that just setting it won’t make it wokr as it needs support in the library.

I am not really versed in the websocket specification or it’s extensions, but I have to ask if you actually need to set any of those. In general k6/ws (or the underlying library linked above) will set the headers to what is needed and supported.

Did you end up adding those headers as something wasn’t working for you? If not - can you just drop all of them?

You can also try the potential future replacement for k6/ws (it will have different import path) that also supports promises and is in practice reimplementation of the browsers’ websocket api. It is still based on the same library as above and the specification implemented just doesn’t let you set headers at all.

Hope this helps you!

Thanks @mstoykov I also found this issue.
I was advised to remove the headers and I am able to connect. FYI that’s the default header k6 is creating:

"headers": {
        "X-Powered-By": "ASP.NET",
        "Connection": "Upgrade",
        "Date": "Thu, 04 Aug 2022 05:41:53 GMT",
        "Server": "Microsoft-IIS/10.0",
        "Upgrade": "websocket",
        "Sec-Websocket-Accept": "eeJFNDahrEnjshauaI4ukPEQFYk=",
        "Set-Cookie": "ARRAffinity=xxx;Secure;Domain=host.com, ARRAffinitySameSite=yyy;Path=/;HttpOnly;SameSite=None;Secure;Domain=host.com",
        "Request-Context": "appId=cid-v1:ea328866-193a-4b53-839f-21f9264077c1"
}

I am experiencing different issue now, which is “handshake was canceled”. :slight_smile: I will take a look at the replacement you have sent, thank you. :slight_smile:

Are you actually connectingto a websocket server or one of the many implementations build on top of it?

Maybe you can use the wireshark and the ssl keylogger to see what actually is being send around and see what happens when it works with a different implementation (browsers support keylogging as well).

I have opened an issue for us to document this better. But as I mention there it’s more or less the same independant of the application that is generating the traffic.