Skip to content

Websocket server unable to negotiate Sec-Websocket-Protocol #328

@bramley-jetcharge

Description

@bramley-jetcharge

My client sends a supported sub protocol in Sec-Websocket-Protocol. I only want to accept the connection if the client sends ocpp1.6.
I implemented it like this:

class DeviceWsSession : WsSession{

    public override bool OnWsConnecting(HttpRequest request, HttpResponse response)
    {
        string subProtocol=null;
        for (int i = 0; i < deviceRequestContext.Headers; i++)
        {
            var header = deviceRequestContext.Header(i);
            if(header.Item1.Equals("Sec-WebSocket-Protocol", StringComparison.OrdinalIgnoreCase)){
                subProtocol = header.Item2;
                break;
            }
        }
        if(subProtocol!="ocpp1.6"){
        //unsupported subprotocol, reject the connection
            response.MakeErrorResponse((int)HttpStatusCode.BadRequest, "unsupported subprotocol");
            Close();
            return false;
        }
        response.SetHeader("Sec-WebSocket-Protocol", subProtocol);
        return true;
        
    }
}

issue 1:

The client is not receiving the selected subprotocol header, and closes the connection. This is easy to reproduce in eg Postman:

Error: Server sent no subprotocol

Handshake Details
Request Method: GET
Status Code: 101 Switching Protocols
Request Headers
Sec-WebSocket-Version: 13
Sec-WebSocket-Key: Hr7wRgkSPHil966y7gpxVw==
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Protocol: ocpp1.6
Sec-WebSocket-Extensions: permessage-deflate; client_max_window_bits
Host: localhost:1102

Response Headers
Connection: Upgrade
Upgrade: websocket
Sec-WebSocket-Accept: AInRhNxNz2oZImm00u32GUcaRn0=
Content-Length: 0

If I remove all of my code, simply return true in OnWsConnecting instead, the same behaviour occurs (seemingly because the library does not send a subprotocol out-of-the-box, fair enough).

issue 2:

In the case where the client sends an unexpected subprotocol I can't support, I want to gracefully close the connection instead. With the above code, Postman shows this error:
Error: Parse Error: Expected HTTP/
Instead of showing the Http 400 bad request, so this is not a graceful disconnect.

I am able to achieve the expected results in Postman using other websocket server libraries, so I'm not sure if this is a limitation of this library or if I'm doing it in the wrong sequence.

Cheers

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions