public void AddWebSocketRequestHandler(string uri, IWebSocketRequestHandler handler) { // TODO: Verify URI lock (m_wsHandlers) { m_wsHandlers.Add(uri, handler); } }
public void AddWebSocketRequestHandler(string uri, IWebSocketRequestHandler handler) { // TODO: Verify URI lock (m_wsHandlers) { m_wsHandlers.Add(uri, handler); } }
public void RegisterHandler(string actionName, IWebSocketRequestHandler action) { try { _registerdHandlers.Add(actionName, action); } catch { // ignore } }
public void RegisterHandler(string actionName, IWebSocketRequestHandler action) { try { _registerdHandlers.Add(actionName,action); } catch(Exception ex) { // todo } }
public void RegisterHandler(string actionName, IWebSocketRequestHandler action) { try { _registerdHandlers.Add(actionName,action); } catch { // ignore } }
public void RegisterHandler(string actionName, IWebSocketRequestHandler action) { try { _registerdHandlers.Add(actionName, action); } catch (Exception ex) { // todo } }
// Registers all IWebSocketRequestHandler's automatically. public static WebSocketEventManager CreateInstance() { var manager = new WebSocketEventManager(); var type = typeof(IWebSocketRequestHandler); var types = AppDomain.CurrentDomain.GetAssemblies() .SelectMany(s => s.GetTypes()) .Where(p => type.IsAssignableFrom(p) && p.IsClass); foreach (var plugin in types) { IWebSocketRequestHandler instance = (IWebSocketRequestHandler)Activator.CreateInstance(plugin); manager.RegisterHandler(instance.Command, instance); } return(manager); }
/// <summary> /// Find the matching handler for the WebSocket request /// </summary> /// <param name="uri"></param> /// <param name="partialUri"></param> /// <returns></returns> internal IWebSocketRequestHandler GetHandlerForWebSocket(string uri, out string partialUri) { partialUri = uri; int length = 0; IWebSocketRequestHandler handler = null; lock (m_wsHandlers) { // Find the longest match foreach (string mapped in m_wsHandlers.Keys) { if (uri.StartsWith(mapped) && (mapped.Length > length)) { length = mapped.Length; handler = m_wsHandlers[mapped]; partialUri = uri.Substring(length); } } } return(handler); }
public WebSocketMiddleware(IWebSocketRequestHandler handler) { _handler = handler; }
/// <summary> /// Handle the HTTP connection /// /// This implementation doesn't support keep alive so each HTTP session /// consists of parsing the request, dispatching to a handler and then /// sending the response before closing the connection. /// </summary> /// <param name="server"></param> /// <param name="input"></param> /// <param name="output"></param> public void ProcessHttpRequest(Stream input, Stream output) { // Set up state HttpRequest request = null; HttpResponse response = null; HttpException parseError = null; HttpContext context = null; // Process the request try { request = ParseRequest(input); if ((request == null) || !m_connected) { return; // Nothing we can do, just drop the connection } // Do we have any content in the body ? if (request.Headers.ContainsKey(HttpHeaders.ContentType)) { if (!request.Headers.ContainsKey(HttpHeaders.ContentLength)) { throw new HttpLengthRequiredException(); } int length; if (!int.TryParse(request.Headers[HttpHeaders.ContentLength], out length)) { throw new HttpLengthRequiredException(); } request.ContentLength = length; if (length > MaxRequestBody) { throw new HttpRequestEntityTooLargeException(); } // Read the data in MemoryStream content = new MemoryStream(); while (m_connected && (content.Length != length)) { ReadData(input); content.Write(m_buffer, 0, m_index); ExtractBytes(m_index); } // Did the connection drop while reading? if (!m_connected) { return; } // Reset the stream location and attach it to the request content.Seek(0, SeekOrigin.Begin); request.Content = content; } // Process the cookies if (request.Headers.ContainsKey(HttpHeaders.Cookie)) { string[] cookies = request.Headers[HttpHeaders.Cookie].Split(CookieSeparator); foreach (string cookie in cookies) { string[] parts = cookie.Split(CookieValueSeparator); Cookie c = new Cookie(); c.Name = parts[0].Trim(); if (parts.Length > 1) { c.Value = parts[1].Trim(); } request.Cookies.Add(c); } } // We have at least a partial request, create the matching response context = new HttpContext(); response = new HttpResponse(); // Apply filters if (m_server.ApplyBeforeFilters(request, response, context)) { // Check for WebSocket upgrade IWebSocketRequestHandler wsHandler = UpgradeToWebsocket(request, response); if (wsHandler != null) { // Apply the after filters here m_server.ApplyAfterFilters(request, response, context); // Write the response back to accept the connection response.Send(output); output.Flush(); // Now we can process the websocket WebSocket ws = new WebSocket(input, output); wsHandler.Connected(ws); ws.Run(); // Once the websocket connection is finished we don't need to do anything else return; } // Dispatch to the handler string partialUri; IHttpRequestHandler handler = m_server.GetHandlerForUri(request.URI, out partialUri); if (handler == null) { throw new HttpNotFoundException(); } handler.HandleRequest(partialUri, request, response, context); } } catch (HttpException ex) { parseError = ex; } catch (Exception) { parseError = new HttpInternalServerErrorException(); } // Do we need to send back an error response ? if (parseError != null) { // TODO: Clear any content that might already be added response.ResponseCode = parseError.ResponseCode; response.ResponseMessage = parseError.Message; } // Apply the after filters here m_server.ApplyAfterFilters(request, response, context); // Write the response response.Send(output); output.Flush(); }
/// <summary> /// Check for an upgrade to a web socket connection. /// </summary> /// <param name="request"></param> /// <param name="response"></param> /// <returns></returns> private IWebSocketRequestHandler UpgradeToWebsocket(HttpRequest request, HttpResponse response) { // Check for required headers if (!(request.Headers.ContainsKey(HttpHeaders.Connection) && request.Headers[HttpHeaders.Connection].ToLower().Contains("upgrade"))) { return(null); } if (!(request.Headers.ContainsKey(HttpHeaders.Upgrade) && request.Headers[HttpHeaders.Upgrade].ToLower().Contains("websocket"))) { return(null); } if (!request.Headers.ContainsKey(SecWebSocketVersion)) { return(null); } int version; if (!(int.TryParse(request.Headers[SecWebSocketVersion], out version) && (version == 13))) { return(null); } if (!request.Headers.ContainsKey(SecWebSocketKey)) { return(null); } // Make sure we have a handler for the URI string partial; IWebSocketRequestHandler handler = m_server.GetHandlerForWebSocket(request.URI, out partial); if (handler == null) { return(null); } // Do we support the protocols requested? string protocol = null; if (request.Headers.ContainsKey(SecWebSocketProtocol)) { foreach (string proto in request.Headers[SecWebSocketProtocol].Split(WebSocketProtocolSeparator)) { if (handler.WillAcceptRequest(partial, proto.Trim())) { protocol = proto.Trim(); break; } } } else if (handler.WillAcceptRequest(partial, "")) { protocol = ""; } if (protocol == null) { return(null); } // Finish the handshake byte[] security = Encoding.UTF8.GetBytes(request.Headers[SecWebSocketKey].Trim() + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"); SHA1CryptoServiceProvider sha1 = new SHA1CryptoServiceProvider(); sha1.Initialize(); sha1.HashCore(security, 0, security.Length); security = sha1.HashFinal(); response.Headers[SecWebSocketAccept] = Convert.ToBase64String(security); response.Headers[HttpHeaders.Upgrade] = "websocket"; response.Headers[HttpHeaders.Connection] = "Upgrade"; response.ResponseCode = HttpResponseCode.SwitchingProtocols; if (protocol.Length > 0) { response.Headers[SecWebSocketProtocol] = protocol; } // And we are done return(handler); }
public WebSocketHandlerMiddleware(RequestDelegate next, IWebSocketRequestHandler requestHandler) { _next = next; _requestHandler = requestHandler; }
/// <summary> /// Handle the HTTP connection /// /// This implementation doesn't support keep alive so each HTTP session /// consists of parsing the request, dispatching to a handler and then /// sending the response before closing the connection. /// </summary> /// <param name="server"></param> /// <param name="input"></param> /// <param name="output"></param> public void ProcessHttpRequest(Stream input, Stream output) { // Set up state HttpRequest request = null; HttpResponse response = null; HttpException parseError = null; HttpContext context = null; SessionHandler sessionHandler = null; // Process the request try { request = ParseRequest(input); if ((request == null) || !m_connected) { return; // Nothing we can do, just drop the connection } // Do we have any content in the body ? if (request.Headers.ContainsKey(HttpHeaders.ContentType)) { if (!request.Headers.ContainsKey(HttpHeaders.ContentLength)) { throw new HttpLengthRequiredException(); } int length; if (!int.TryParse(request.Headers[HttpHeaders.ContentLength], out length)) { throw new HttpLengthRequiredException(); } request.ContentLength = length; if (length > MaxRequestBody) { throw new HttpRequestEntityTooLargeException(); } // Read the data in MemoryStream content = new MemoryStream(); //23.08.2016 - Changes for supporting POST Method int contentCopyCounter = 0; int bodyReadCount = 0; while (m_connected && (content.Length != length)) { if (contentCopyCounter > 0) { int bytesToRead = ((length - bodyReadCount) > InputBufferSize) ? InputBufferSize : (length - bodyReadCount); ReadData(input, bytesToRead); } bodyReadCount += m_index; content.Write(m_buffer, 0, m_index); ExtractBytes(m_index); contentCopyCounter++; } //23.08.2016 - End of Changes for supporting POST Method // Did the connection drop while reading? if (!m_connected) { return; } // Reset the stream location and attach it to the request content.Seek(0, SeekOrigin.Begin); request.Content = content; } // Process the cookies if (request.Headers.ContainsKey(HttpHeaders.Cookie)) { string[] cookies = request.Headers[HttpHeaders.Cookie].Split(CookieSeparator); foreach (string cookie in cookies) { string[] parts = cookie.Split(CookieValueSeparator); Cookie c = new Cookie(); c.Name = parts[0].Trim(); if (parts.Length > 1) { c.Value = parts[1].Trim(); } request.Cookies.Add(c); } } // We have at least a partial request, create the matching response context = new HttpContext(); response = new HttpResponse(); //Get session id from cookies var sessionId = GetSessionIdentifier(request.Cookies); var isNewRequest = string.IsNullOrEmpty(sessionId); if (isNewRequest) { sessionId = Utilities.GetNewSessionIdentifier(); } sessionHandler = new SessionHandler(sessionId, m_server.SessionStorageHandler); context.SessionHandler = sessionHandler; sessionHandler.DestroyExpiredSessions(); //Update session data if (isNewRequest) { sessionHandler.SaveSessionData(); response.Cookies.Add(new Cookie(SessionName, sessionHandler.SessionId)); } else { sessionHandler.UpdateSessionTimeOut(); var isRetrieved = sessionHandler.GetSessionData(); if (!isRetrieved) { sessionId = Utilities.GetNewSessionIdentifier(); sessionHandler = new SessionHandler(sessionId, m_server.SessionStorageHandler); context.SessionHandler = sessionHandler; sessionHandler.SaveSessionData(); response.Cookies.Add(new Cookie(SessionName, sessionHandler.SessionId)); } } // Apply filters if (m_server.ApplyBeforeFilters(request, response, context)) { // Check for WebSocket upgrade IWebSocketRequestHandler wsHandler = UpgradeToWebsocket(request, response); if (wsHandler != null) { // Apply the after filters here m_server.ApplyAfterFilters(request, response, context); // Write the response back to accept the connection /////////////////////////////////Changes done locally to fix HTTP 1.1 on Safari 10 websocket error on 22.11.2016///////////////////// response.Send(output, HttpVersion.Ver1_1); output.Flush(); // Now we can process the websocket WebSocket ws = new WebSocket(input, output); wsHandler.Connected(ws); ws.Run(); // Once the websocket connection is finished we don't need to do anything else return; } // Dispatch to the handler string partialUri; IHttpRequestHandler handler = m_server.GetHandlerForUri(request.URI, out partialUri); if (handler == null) { throw new HttpNotFoundException(); } handler.HandleRequest(partialUri, request, response, context); } } catch (HttpException ex) { parseError = ex; } catch (Exception) { parseError = new HttpInternalServerErrorException(); } // Do we need to send back an error response ? if (parseError != null) { // TODO: Clear any content that might already be added response.ResponseCode = parseError.ResponseCode; response.ResponseMessage = parseError.Message; } // Apply the after filters here m_server.ApplyAfterFilters(request, response, context); //Update the session before sending the response if (sessionHandler != null) { if (sessionHandler.IsChanged) { sessionHandler.SaveSessionData(); } if (sessionHandler.IsSessionDestroyed) { sessionHandler.IsSessionDestroyed = false; response.Cookies.Add(new Cookie(SessionName, sessionHandler.SessionId)); } } // Write the response response.Send(output); output.Flush(); }