public void CannotRegisterAListenerWithoutASubProtocol() { IWebSocketListener listener = this._SubprotocolListener(null); var registry = new WebSocketListenerRegistry(); Assert.Throws <ArgumentNullException>(() => registry.TryRegister(listener)); }
public void CanRegisterAListener() { IWebSocketListener listener = this._SubprotocolListener("abc"); var registry = new WebSocketListenerRegistry(); Assert.True(registry.TryRegister(listener)); }
async Task ProcessRequestAsync(HttpContext context, IWebSocketListener listener, string correlationId) { Preconditions.CheckNotNull(context, nameof(context)); Preconditions.CheckNotNull(context.Connection, nameof(context.Connection)); Preconditions.CheckNotNull(context.Connection.RemoteIpAddress, nameof(context.Connection.RemoteIpAddress)); Preconditions.CheckNotNull(correlationId, nameof(correlationId)); Events.WebSocketSubProtocolSelected(context.TraceIdentifier, listener.SubProtocol, correlationId); WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(listener.SubProtocol); Option <EndPoint> localEndPoint = Option.None <EndPoint>(); if (context.Connection.LocalIpAddress != null) { localEndPoint = Option.Some <EndPoint>(new IPEndPoint(context.Connection.LocalIpAddress, context.Connection.LocalPort)); } var remoteEndPoint = new IPEndPoint(context.Connection.RemoteIpAddress, context.Connection.RemotePort); X509Certificate2 cert = await context.Connection.GetClientCertificateAsync(); if (cert != null) { IList <X509Certificate2> certChain = context.GetClientCertificateChain(); await listener.ProcessWebSocketRequestAsync(webSocket, localEndPoint, remoteEndPoint, correlationId, cert, certChain); } else { await listener.ProcessWebSocketRequestAsync(webSocket, localEndPoint, remoteEndPoint, correlationId); } Events.WebSocketRequestCompleted(context.TraceIdentifier, correlationId); }
public void CannotRegisterTheSameListenerTwice() { IWebSocketListener listener = this._SubprotocolListener("abc"); var registry = new WebSocketListenerRegistry(); registry.TryRegister(listener); Assert.False(registry.TryRegister(listener)); }
public void CanUnregisterAListener() { IWebSocketListener inListener = this._SubprotocolListener("abc"); var registry = new WebSocketListenerRegistry(); registry.TryRegister(inListener); Assert.True(registry.TryUnregister("abc", out IWebSocketListener outListener)); Assert.Equal(inListener, outListener); }
async Task ProcessRequestAsync(HttpContext context, IWebSocketListener listener, string correlationId) { Preconditions.CheckNotNull(context, nameof(context)); Preconditions.CheckNotNull(context.Connection, nameof(context.Connection)); Preconditions.CheckNotNull(context.Connection.RemoteIpAddress, nameof(context.Connection.RemoteIpAddress)); Preconditions.CheckNotNull(correlationId, nameof(correlationId)); Events.WebSocketSubProtocolSelected(context.TraceIdentifier, listener.SubProtocol, correlationId); WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(listener.SubProtocol); Option <EndPoint> localEndPoint = Option.None <EndPoint>(); if (context.Connection.LocalIpAddress != null) { localEndPoint = Option.Some <EndPoint>(new IPEndPoint(context.Connection.LocalIpAddress, context.Connection.LocalPort)); } var remoteEndPoint = new IPEndPoint(context.Connection.RemoteIpAddress, context.Connection.RemotePort); X509Certificate2 cert = await context.Connection.GetClientCertificateAsync(); IAuthenticator proxyAuthenticator = null; if (cert == null) { try { var certExtractor = await this.httpProxiedCertificateExtractorProvider; // if not certificate in header it returns null, no api proxy authentication needed in this case // if certificate was set in header it means it was forwarded by api proxy and authenticates api proxy by sas token // and throws AuthenticationException if api proxy was not authenticated or returns the certificate if api proxy authentication succeeded cert = (await certExtractor.GetClientCertificate(context)).OrDefault(); } catch (AuthenticationException ex) { Events.AuthenticationApiProxyFailed(remoteEndPoint.ToString(), ex); // Set authenticator to unauthorize the call from subprotocol level (Mqtt or Amqp) proxyAuthenticator = new NullAuthenticator(); cert = context.GetForwardedCertificate(); } } if (cert != null) { IList <X509Certificate2> certChain = context.GetClientCertificateChain(); await listener.ProcessWebSocketRequestAsync(webSocket, localEndPoint, remoteEndPoint, correlationId, cert, certChain, proxyAuthenticator); } else { await listener.ProcessWebSocketRequestAsync(webSocket, localEndPoint, remoteEndPoint, correlationId); } Events.WebSocketRequestCompleted(context.TraceIdentifier, correlationId); }
public void CannotUnregisterAListenerWithANullOrWhitespaceSubProtocol() { IWebSocketListener inListener = this._SubprotocolListener("abc"); var registry = new WebSocketListenerRegistry(); registry.TryRegister(inListener); Assert.Throws <ArgumentException>(() => registry.TryUnregister(null, out IWebSocketListener _)); Assert.Throws <ArgumentException>(() => registry.TryUnregister(string.Empty, out IWebSocketListener _)); Assert.Throws <ArgumentException>(() => registry.TryUnregister(" ", out IWebSocketListener _)); }
public async Task AlwaysInvokesTheFirstMatchingListener() { IWebSocketListener abcListener = this._SubprotocolListener("abc"); IWebSocketListener xyzListener = this._SubprotocolListener("xyz"); var registry = new WebSocketListenerRegistry(); registry.TryRegister(abcListener); registry.TryRegister(xyzListener); HttpContext httpContext = this._ContextWithRequestedSubprotocols("xyz", "abc"); Assert.True(await registry.InvokeAsync(httpContext, "123")); Mock.Get(xyzListener).Verify(wsl => wsl.ProcessWebSocketRequestAsync(httpContext, "123")); }
public void AlwaysInvokesTheFirstMatchingListener() { IWebSocketListener abcListener = this._SubprotocolListener("abc"); IWebSocketListener xyzListener = this._SubprotocolListener("xyz"); var registry = new WebSocketListenerRegistry(); registry.TryRegister(abcListener); registry.TryRegister(xyzListener); HttpContext httpContext = this._ContextWithRequestedSubprotocols("xyz", "abc"); var listener = registry.GetListener(httpContext.WebSockets.WebSocketRequestedProtocols); Assert.True(listener.HasValue); listener.ForEach(l => Assert.Equal(l.SubProtocol, "xyz")); //Mock.Get(xyzListener).Verify(wsl => wsl.ProcessWebSocketRequestAsync(It.IsAny<WebSocket>(), It.IsAny<string>(), It.IsAny<EndPoint>(), It.IsAny<EndPoint>(), It.IsAny<string>())); }
public WebSocketDispatcher(Uri locationUri, ServerEtiquette etiquette, IWebSocketHandlerFactory handlerFactory, X509Certificate serverCertificate) { if (locationUri == null) { throw new ArgumentNullException("locationUri"); } if (handlerFactory == null) { throw new ArgumentNullException("handlerFactory"); } this.handlerFactory = handlerFactory; clientsByMetadata = new Dictionary <string, List <IWebSocket> >(); listener = new WebSocketListener(locationUri, etiquette, serverCertificate); listener.Start(OnHandShaken); }
public bool TryUnregister(string subProtocol, out IWebSocketListener webSocketListener) { Preconditions.CheckNonWhiteSpace(subProtocol, nameof(subProtocol)); return(this.webSocketListeners.TryRemove(subProtocol, out webSocketListener)); }
public bool TryRegister(IWebSocketListener webSocketListener) { Preconditions.CheckNotNull(webSocketListener, nameof(webSocketListener)); return(this.webSocketListeners.TryAdd(webSocketListener.SubProtocol, webSocketListener)); }
async Task ProcessRequestAsync(HttpContext context, IWebSocketListener listener, string correlationId) { Preconditions.CheckNotNull(context, nameof(context)); Preconditions.CheckNotNull(context.Connection, nameof(context.Connection)); Preconditions.CheckNotNull(context.Connection.RemoteIpAddress, nameof(context.Connection.RemoteIpAddress)); Preconditions.CheckNotNull(correlationId, nameof(correlationId)); Events.WebSocketSubProtocolSelected(context.TraceIdentifier, listener.SubProtocol, correlationId); WebSocket webSocket = await context.WebSockets.AcceptWebSocketAsync(listener.SubProtocol); Option <EndPoint> localEndPoint = Option.None <EndPoint>(); if (context.Connection.LocalIpAddress != null) { localEndPoint = Option.Some <EndPoint>(new IPEndPoint(context.Connection.LocalIpAddress, context.Connection.LocalPort)); } var remoteEndPoint = new IPEndPoint(context.Connection.RemoteIpAddress, context.Connection.RemotePort); X509Certificate2 cert = await context.Connection.GetClientCertificateAsync(); if (cert == null) { // If the connection came through the API proxy, the client cert // would have been forwarded in a custom header. But since TLS // termination occurs at the proxy, we can only trust this custom // header if the request came through port 8080, which an internal // port only accessible within the local Docker vNet. if (context.Connection.LocalPort == Constants.ApiProxyPort) { if (context.Request.Headers.TryGetValue(Constants.ClientCertificateHeaderKey, out StringValues clientCertHeader) && clientCertHeader.Count > 0) { Events.AuthenticationApiProxy(context.Connection.RemoteIpAddress.ToString()); string clientCertString = WebUtility.UrlDecode(clientCertHeader.First()); try { var clientCertificateBytes = Encoding.UTF8.GetBytes(clientCertString); cert = new X509Certificate2(clientCertificateBytes); } catch (Exception ex) { Events.InvalidCertificate(ex, remoteEndPoint.ToString()); throw; } } } } if (cert != null) { IList <X509Certificate2> certChain = context.GetClientCertificateChain(); await listener.ProcessWebSocketRequestAsync(webSocket, localEndPoint, remoteEndPoint, correlationId, cert, certChain); } else { await listener.ProcessWebSocketRequestAsync(webSocket, localEndPoint, remoteEndPoint, correlationId); } Events.WebSocketRequestCompleted(context.TraceIdentifier, correlationId); }