Skip to content

Hooking into the HTTP negotiation

vtortola edited this page May 26, 2014 · 6 revisions

It is possible to hook into the HTTP negotiation with the delegate provided in the server configuration and check/add cookies or return a custom HTTP status code.

The only thing you need is to provide a handler of this type in the configuration:

void OnHttpNegotiationDelegate(WebSocketHttpRequest request, WebSocketHttpResponse response)

The handler will be executed as part of the HTTP negotiation process. Keep in mind that the HTTP negotiations happen in parallel, so if you introduce a mutual exclusion element (like a lock) in the handler, you will probably reduce the connection rate.

Please note that cookies are not sent when using an IP address as connection target.

Examples

Identifying the connection with cookies

new WebSocketListenerOptions() 
{ 
    PingTimeout = TimeSpan.FromSeconds(10), 
    SubProtocols = new[] { "text" },
    OnHttpNegotiation = (request, response)=>
    {
        if(request.Cookies["ConnectionId"] == null)
            response.Cookies.Add(new Cookie("ConnectionId", Guid.NewGuid().ToString()));
    }
}

You may retrieve that ConnectionId by for example doing:

Guid connectionId = Guid.Empty;
Cookie cookie = ws.HttpRequest.Cookies["ConnectionId"] ?? ws.HttpResponse.Cookies["ConnectionId"];
if (cookie == null || !Guid.TryParse(cookie.Value, out connectionId))
    throw new WebSocketException("The connection has not identifier");

Rejecting connections that are not authenticated

new WebSocketListenerOptions() 
{ 
    PingTimeout = TimeSpan.FromSeconds(10), 
    SubProtocols = new[] { "text" },
    OnHttpNegotiation = (request, response)=>
    {
        var authCookie = request.Cookies[".ASPXAUTH"];
        if(authCookie == null || !IsAuthCookieValid(authCookie.Value))
            response.Status = HttpStatusCode.Unauthorized;
    }
}

Remember you need to share the "machineKey" between your web site and your websocket server if you want to be able of reading the authentication cookie content.