/// <summary>
        /// Create the web socket response headers.
        /// </summary>
        /// <param name="webSocketContext">The current web socket context.</param>
        private void CreateResponseHeaders(Nequeo.Net.WebSockets.WebSocketContext webSocketContext)
        {
            // If this is a WebSocket request then complete the handshaking.
            if (webSocketContext.WebSocketRequest.IsWebSocketRequest)
            {
                // Get the sec web socket accept key.
                byte[] webSocketKey       = Nequeo.Cryptography.Hashcode.GetHashcodeSHA1Raw(webSocketContext.WebSocketRequest.SecWebSocketKey + Common.Resource.MagicGuid);
                string secWebSocketAccept = System.Convert.ToBase64String(webSocketKey);

                // Create the response and write the data back to the client.
                Nequeo.Net.WebSockets.WebSocketResponse response = webSocketContext.WebSocketResponse;
                response.SecWebSocketAccept = secWebSocketAccept;
                response.ContentLength      = 0;
                response.Server             = base.Name;

                // If protocols have been sent from the client
                // then assign the first one found.
                if (webSocketContext.WebSocketRequest.SecWebSocketProtocols != null && webSocketContext.WebSocketRequest.SecWebSocketProtocols.Length > 0)
                {
                    response.SecWebSocketProtocol = webSocketContext.WebSocketRequest.SecWebSocketProtocols[0];
                }

                // If extensions have been sent from the client
                // then assign the first one found.
                if (webSocketContext.WebSocketRequest.SecWebSocketExtensions != null && webSocketContext.WebSocketRequest.SecWebSocketExtensions.Length > 0)
                {
                    response.SecWebSocketExtensions = webSocketContext.WebSocketRequest.SecWebSocketExtensions[0];
                }

                // Indicate that handshaking is complete.
                webSocketContext.HandshakeComplete = true;
            }
        }
        /// <summary>
        /// Create the web socket context.
        /// </summary>
        /// <param name="context">The current client context.</param>
        /// <returns>The web socket context.</returns>
        private Nequeo.Net.WebSockets.WebSocketContext CreateWebSocketContext(Nequeo.Net.Provider.Context context)
        {
            // Get the underlying web context.
            Nequeo.Net.WebContext webContext = CreateWebContext(context);

            // Create the new web socket context from the web context.
            Nequeo.Net.WebSockets.WebSocketContext webSocketContext = Nequeo.Net.WebSockets.WebSocketContext.CreateFrom(webContext);

            // Assign response and request data.
            webSocketContext.WebSocketResponse        = new WebSocketResponse();
            webSocketContext.WebSocketRequest         = new WebSocketRequest();
            webSocketContext.WebSocketResponse.Output = webContext.WebResponse.Output;
            webSocketContext.WebSocketRequest.Input   = webContext.WebRequest.Input;

            // Return the request context.
            return(webSocketContext);
        }
        /// <summary>
        /// Check to see if the request is a web socket.
        /// </summary>
        /// <param name="webSocketContext">The current web socket context.</param>
        private void CheckIfWebSocketRequest(Nequeo.Net.WebSockets.WebSocketContext webSocketContext)
        {
            // Make sure all handshaking has complete before continuing.
            if (!webSocketContext.HandshakeComplete)
            {
                // Get the request and response.
                Nequeo.Net.WebSockets.WebSocketRequest  request    = webSocketContext.WebSocketRequest;
                Nequeo.Net.WebSockets.WebSocketResponse response   = webSocketContext.WebSocketResponse;
                Nequeo.Net.Http.Common.HttpStatusCode   statusCode = null;

                // If not a web socket request.
                if (!webSocketContext.WebSocketRequest.IsWebSocketRequest)
                {
                    // Get the bad request.
                    statusCode = Nequeo.Net.Http.Utility.GetStatusCode(400);

                    // Send bad request.
                    response.Server            = base.Name;
                    response.ContentLength     = 0;
                    response.StatusCode        = statusCode.Code;
                    response.StatusDescription = statusCode.Description;
                    response.ProtocolVersion   = request.ProtocolVersion;
                }
                else
                {
                    // Get the internal error.
                    statusCode = Nequeo.Net.Http.Utility.GetStatusCode(500);

                    // Send internal error.
                    response.Server            = base.Name;
                    response.ContentLength     = 0;
                    response.StatusCode        = statusCode.Code;
                    response.StatusDescription = statusCode.Description;
                    response.ProtocolVersion   = request.ProtocolVersion;
                }

                // Not valid.
                throw new Exception("Not a valid WebSocket request.");
            }
        }
Example #4
0
 /// <summary>
 /// Create the web socket context from the web context.
 /// </summary>
 /// <param name="webContext">The web context to create from.</param>
 /// <returns>The web socket server context.</returns>
 public static WebSocketContext CreateFrom(Nequeo.Net.WebContext webContext)
 {
     Nequeo.Net.WebSockets.WebSocketContext webSocketContext = new Nequeo.Net.WebSockets.WebSocketContext();
     webSocketContext.Context             = webContext.Context;
     webSocketContext.IsStartOfConnection = webContext.IsStartOfConnection;
     webSocketContext.IsAuthenticated     = webContext.IsAuthenticated;
     webSocketContext.IsSecureConnection  = webContext.IsSecureConnection;
     webSocketContext.Name              = webContext.Name;
     webSocketContext.NumberOfClients   = webContext.NumberOfClients;
     webSocketContext.Port              = webContext.Port;
     webSocketContext.RemoteEndPoint    = webContext.RemoteEndPoint;
     webSocketContext.ServerEndPoint    = webContext.ServerEndPoint;
     webSocketContext.ServiceName       = webContext.ServiceName;
     webSocketContext.UniqueIdentifier  = webContext.UniqueIdentifier;
     webSocketContext.ConnectionID      = webContext.ConnectionID;
     webSocketContext.SessionID         = webContext.SessionID;
     webSocketContext.User              = webContext.User;
     webSocketContext.SocketState       = webContext.SocketState;
     webSocketContext.IsAsyncMode       = webContext.IsAsyncMode;
     webSocketContext.HandshakeComplete = false;
     return(webSocketContext);
 }
        /// <summary>
        /// On received action handler.
        /// </summary>
        /// <param name="context">The current client context.</param>
        private void OnReceivedActionHandler(Nequeo.Net.Provider.Context context)
        {
            try
            {
                // Store data until all headers have been read.
                if (Nequeo.Net.Utility.IsParse2CRLF(context.Request.Input, context.RequestBufferStore, _maxHeaderBufferStore))
                {
                    // Create the web socket context and set the headers.
                    Nequeo.Net.WebSockets.WebSocketContext webSocketContext = CreateWebSocketContext(context);

                    // Get the headers from the stream and assign the request data.
                    bool headersExist = Nequeo.Net.WebSockets.Utility.SetRequestHeaders(webSocketContext,
                                                                                        base.HeaderTimeout, base.MaximumReadLength, context.RequestBufferStore);

                    // Create the response headers.
                    CreateResponseHeaders(webSocketContext);

                    // Make sure all handshaking has complete before continuing.
                    if (!webSocketContext.HandshakeComplete)
                    {
                        // Check to see if the request is a web socket.
                        CheckIfWebSocketRequest(webSocketContext);
                    }
                    else
                    {
                        // Indicate that all web sockets after handshaking
                        // is complete will run in async mode.
                        webSocketContext.IsAsyncMode = true;

                        // Create the central web socket context.
                        CentralWebSocketContext centralWebSocketContext = new CentralWebSocketContext(webSocketContext);
                        centralWebSocketContext.ConnectionID          = webSocketContext.ConnectionID;
                        centralWebSocketContext.Cookies               = webSocketContext.WebSocketRequest.Cookies;
                        centralWebSocketContext.Headers               = webSocketContext.WebSocketRequest.Headers;
                        centralWebSocketContext.IsAuthenticated       = webSocketContext.IsAuthenticated;
                        centralWebSocketContext.IsSecureConnection    = webSocketContext.IsSecureConnection;
                        centralWebSocketContext.SecWebSocketKey       = webSocketContext.WebSocketRequest.SecWebSocketKey;
                        centralWebSocketContext.SecWebSocketProtocols = webSocketContext.WebSocketRequest.SecWebSocketProtocols;
                        centralWebSocketContext.SecWebSocketVersion   = webSocketContext.WebSocketRequest.SecWebSocketVersion;
                        centralWebSocketContext.SessionID             = webSocketContext.SessionID;
                        centralWebSocketContext.SocketState           = webSocketContext.SocketState;
                        centralWebSocketContext.UniqueIdentifier      = webSocketContext.UniqueIdentifier;
                        centralWebSocketContext.Url  = webSocketContext.WebSocketRequest.Url;
                        centralWebSocketContext.User = webSocketContext.User;

                        // If the event has been assigned.
                        if (OnWebSocketContext != null)
                        {
                            OnWebSocketContext(this, centralWebSocketContext);
                        }

                        // Write the response to the client.
                        Nequeo.Net.WebSockets.WebSocketResponse response = webSocketContext.WebSocketResponse;
                        response.WriteWebSocketHeaders();

                        // Create and assign the web socket.
                        Nequeo.Net.WebSockets.WebSocket webSocket = new Nequeo.Net.WebSockets.WebSocket(centralWebSocketContext, response.ProtocolVersion);
                        centralWebSocketContext.WebSocket = webSocket;

                        // Save the web context state objects.
                        SaveWebContext(context, webSocketContext);
                    }
                }

                // If the maximum request buffer store has been reached then close the connection.
                if (context.RequestBufferStore.Length > _maxHeaderBufferStore)
                {
                    throw new Exception("Maximum request buffer store has been reached.");
                }
            }
            catch (Exception)
            {
                // Close the connection and release all resources used for communication.
                context.Close();
            }
        }
Example #6
0
        /// <summary>
        /// Set the request headers from the input stream within the current http context.
        /// </summary>
        /// <param name="webSocketContext">The current web socket context.</param>
        /// <param name="timeout">The maximum time in milliseconds to wait for the end of the header data; -1 wait Indefinitely.</param>
        /// <param name="maxReadLength">The maximun number of bytes to read before cancelling (must be greater then zero).</param>
        /// <param name="requestBufferStore">The request buffer store stream.</param>
        /// <exception cref="System.Exception"></exception>
        /// <returns>True if the headers have been found; else false.</returns>
        public static bool SetRequestHeaders(Nequeo.Net.WebSockets.WebSocketContext webSocketContext, long timeout = -1, int maxReadLength = 0, System.IO.Stream requestBufferStore = null)
        {
            // Header has not been found at this point.
            string requestMethod   = "";
            string protocolVersion = "";

            byte[]           rawData = null;
            List <NameValue> headers = null;

            // Web socket context is null.
            if (webSocketContext == null)
            {
                return(false);
            }

            // Web socket request context is null.
            if (webSocketContext.WebSocketRequest == null)
            {
                return(false);
            }

            // Web socket request context stream is null.
            if (webSocketContext.WebSocketRequest.Input == null)
            {
                return(false);
            }

            // If not using the buffer store.
            if (requestBufferStore == null)
            {
                // We need to wait until we get all the header
                // data then send the context to the server.
                headers = Nequeo.Net.Utility.
                          ParseHeaders(webSocketContext.WebSocketRequest.Input, out requestMethod, ref rawData, timeout, maxReadLength);
            }
            else
            {
                // We need to wait until we get all the header
                // data then send the context to the server.
                headers = Nequeo.Net.Utility.
                          ParseHeaders(webSocketContext.RequestBufferStore, out requestMethod, ref rawData, timeout, maxReadLength);
            }

            // If headers exist then all has been found.
            if (headers != null)
            {
                // Set all the request headers.
                webSocketContext.WebSocketRequest.ReadWebSocketHeaders(headers, requestMethod);
                protocolVersion = webSocketContext.WebSocketRequest.ProtocolVersion;
                webSocketContext.WebSocketRequest.HeadersFound = true;

                // If the client is using protocol version "HTTP/1.1"
                if (protocolVersion.ToUpper().Trim().Replace(" ", "").Contains("HTTP/1.1"))
                {
                    // Do nothing.
                }

                // If the client is using protocol version "HTTP/2.0".
                if (protocolVersion.ToUpper().Trim().Replace(" ", "").Contains("HTTP/2"))
                {
                    // Do nothing.
                }

                // Set the user principle if credentials
                // have been passed.
                if (webSocketContext.WebSocketRequest.Credentials != null)
                {
                    // Add the credentials.
                    Nequeo.Security.IdentityMember identity =
                        new Nequeo.Security.IdentityMember(
                            webSocketContext.WebSocketRequest.Credentials.UserName,
                            webSocketContext.WebSocketRequest.Credentials.Password,
                            webSocketContext.WebSocketRequest.Credentials.Domain);

                    Nequeo.Security.AuthenticationType authType = Nequeo.Security.AuthenticationType.None;
                    try
                    {
                        // Attempt to get the authentication type.
                        authType = (Nequeo.Security.AuthenticationType)
                                   Enum.Parse(typeof(Nequeo.Security.AuthenticationType), webSocketContext.WebSocketRequest.AuthorizationType);
                    }
                    catch { }

                    // Set the cuurent authentication schema.
                    identity.AuthenticationSchemes = authType;

                    // Create the principal.
                    Nequeo.Security.PrincipalMember principal = new Nequeo.Security.PrincipalMember(identity, null);

                    // Assign the principal
                    webSocketContext.User = principal;
                }

                return(true);
            }
            else
            {
                return(false);
            }
        }