Beispiel #1
0
		public void AddWebSocketRequestHandler(string uri, IWebSocketRequestHandler handler)
		{
			// TODO: Verify URI
			lock (m_wsHandlers)
			{
				m_wsHandlers.Add(uri, handler);
			}
		}
Beispiel #2
0
 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
     } 
 }
Beispiel #6
0
 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);
        }
Beispiel #8
0
        /// <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;
 }
Beispiel #10
0
        /// <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();
        }
Beispiel #11
0
        /// <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);
        }
Beispiel #12
0
 public WebSocketHandlerMiddleware(RequestDelegate next, IWebSocketRequestHandler requestHandler)
 {
     _next           = next;
     _requestHandler = requestHandler;
 }
Beispiel #13
0
        /// <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();
        }