/// <summary>
            /// Handles incoming raw frames and translates them into WebSocketFrame(s)
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleIncomingFrames(ISockNetChannel channel, ref object data)
            {
                if (!(data is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer stream           = (ChunkedBuffer)data;
                long          startingPosition = stream.ReadPosition;

                try
                {
                    WebSocketFrame frame = WebSocketFrame.ParseFrame(stream.Stream);

                    if (combineContinuations)
                    {
                        if (frame.IsFinished)
                        {
                            UpdateContinuation(ref continuationFrame, frame);

                            data = continuationFrame;
                            continuationFrame = null;
                        }
                        else
                        {
                            UpdateContinuation(ref continuationFrame, frame);
                        }
                    }
                    else
                    {
                        data = frame;
                    }

                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received WebSocket message. Size: {0}, Type: {1}, IsFinished: {2}", frame.Data.Length, Enum.GetName(typeof(WebSocketFrame.WebSocketFrameOperation), frame.Operation), frame.IsFinished);
                    }
                }
                catch (EndOfStreamException)
                {
                    // websocket frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // websocket frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (Exception e)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to parse web-socket request", e);

                    channel.Close();
                }
            }
Example #2
0
            /// <summary>
            /// Handles the WebSocket handshake.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleHandshake(ISockNetChannel channel, ref HttpRequest request)
            {
                string connection  = request.Header["Connection"];
                string upgrade     = request.Header["Upgrade"];
                string securityKey = request.Header[WebSocketUtil.WebSocketKeyHeader];

                if (connection != null && upgrade != null && securityKey != null && "websocket".Equals(upgrade.Trim().ToLower()) && "upgrade".Equals(connection.Trim().ToLower()))
                {
                    string[] requestProtocols = request.Headers[WebSocketUtil.WebSocketProtocolHeader];

                    List <string> handledProtocols = new List <string>();
                    if (requestProtocols != null && protocolDelegate != null)
                    {
                        for (int i = 0; i < requestProtocols.Length; i++)
                        {
                            if (protocolDelegate(channel, requestProtocols[i]))
                            {
                                handledProtocols.Add(requestProtocols[i]);
                            }
                        }
                    }

                    HttpResponse response = new HttpResponse(channel.BufferPool)
                    {
                        Version = "HTTP/1.1",
                        Code    = "101",
                        Reason  = "Switching Protocols"
                    };
                    response.Header["Upgrade"]    = "websocket";
                    response.Header["Connection"] = "Upgrade";
                    response.Header[WebSocketUtil.WebSocketAcceptHeader]   = WebSocketUtil.GenerateAccept(securityKey);
                    response.Header[WebSocketUtil.WebSocketProtocolHeader] = string.Join(",", handledProtocols.ToArray());

                    channel.Send(response);

                    channel.RemoveModule(httpModule);

                    channel.Pipe.AddIncomingFirst <object>(HandleIncomingFrames);
                    channel.Pipe.AddOutgoingLast <object>(HandleOutgoingFrames);
                }
                else
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Expecting upgrade request.");

                    channel.Close();
                }
            }
            /// <summary>
            /// Handles the WebSocket handshake.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleHandshake(ISockNetChannel channel, ref HttpResponse data)
            {
                if (expectedAccept.Equals(data.Header[WebSocketUtil.WebSocketAcceptHeader]))
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Established Web-Socket connection.");
                    channel.Pipe.RemoveIncoming <HttpResponse>(HandleHandshake);
                    channel.Pipe.AddIncomingFirst <object>(HandleIncomingFrames);
                    channel.Pipe.AddOutgoingLast <object>(HandleOutgoingFrames);

                    channel.RemoveModule(httpModule);

                    if (onWebSocketEstablished != null)
                    {
                        onWebSocketEstablished(channel);
                    }
                }
                else
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Web-Socket handshake incomplete.");

                    channel.Close();
                }
            }
            /// <summary>
            /// Handles incoming raw frames and translates them into WebSocketFrame(s)
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleIncomingFrames(ISockNetChannel channel, ref object data)
            {
                if (!(data is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer stream = (ChunkedBuffer)data;
                long startingPosition = stream.ReadPosition;

                try
                {
                    WebSocketFrame frame = WebSocketFrame.ParseFrame(stream.Stream);

                    if (combineContinuations)
                    {
                        if (frame.IsFinished)
                        {
                            UpdateContinuation(ref continuationFrame, frame);

                            data = continuationFrame;
                            continuationFrame = null;
                        }
                        else
                        {
                            UpdateContinuation(ref continuationFrame, frame);
                        }
                    }
                    else
                    {
                        data = frame;
                    }

                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received WebSocket message. Size: {0}, Type: {1}, IsFinished: {2}", frame.Data.Length, Enum.GetName(typeof(WebSocketFrame.WebSocketFrameOperation), frame.Operation), frame.IsFinished);
                    }
                }
                catch (EndOfStreamException)
                {
                    // websocket frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // websocket frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (Exception e)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to parse web-socket request", e);

                    channel.Close();
                }
            }
            /// <summary>
            /// Handles the WebSocket handshake.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleHandshake(ISockNetChannel channel, ref HttpResponse data)
            {
                if (expectedAccept.Equals(data.Header[WebSocketUtil.WebSocketAcceptHeader]))
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Established Web-Socket connection.");
                    channel.Pipe.RemoveIncoming<HttpResponse>(HandleHandshake);
                    channel.Pipe.AddIncomingFirst<object>(HandleIncomingFrames);
                    channel.Pipe.AddOutgoingLast<object>(HandleOutgoingFrames);

                    channel.RemoveModule(httpModule);

                    if (onWebSocketEstablished != null)
                    {
                        onWebSocketEstablished(channel);
                    }
                }
                else
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Web-Socket handshake incomplete.");

                    channel.Close();
                }
            }
            /// <summary>
            /// Handles the WebSocket handshake.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleHandshake(ISockNetChannel channel, ref HttpRequest request)
            {
                string connection = request.Header["Connection"];
                string upgrade = request.Header["Upgrade"];
                string securityKey = request.Header[WebSocketUtil.WebSocketKeyHeader];

                if (connection != null && upgrade != null && securityKey != null && "websocket".Equals(upgrade.Trim().ToLower()) && "upgrade".Equals(connection.Trim().ToLower()))
                {
                    string[] requestProtocols = request.Headers[WebSocketUtil.WebSocketProtocolHeader];

                    List<string> handledProtocols = new List<string>();
                    if (requestProtocols != null && protocolDelegate != null)
                    {
                        for (int i = 0; i < requestProtocols.Length; i++)
                        {
                            if (protocolDelegate(channel, requestProtocols[i]))
                            {
                                handledProtocols.Add(requestProtocols[i]);
                            }
                        }
                    }

                    HttpResponse response = new HttpResponse(channel.BufferPool)
                    {
                        Version = "HTTP/1.1",
                        Code = "101",
                        Reason = "Switching Protocols"
                    };
                    response.Header["Upgrade"] = "websocket";
                    response.Header["Connection"] = "Upgrade";
                    response.Header[WebSocketUtil.WebSocketAcceptHeader] = WebSocketUtil.GenerateAccept(securityKey);
                    response.Header[WebSocketUtil.WebSocketProtocolHeader] = string.Join(",", handledProtocols.ToArray());

                    channel.Send(response);

                    channel.RemoveModule(httpModule);

                    channel.Pipe.AddIncomingFirst<object>(HandleIncomingFrames);
                    channel.Pipe.AddOutgoingLast<object>(HandleOutgoingFrames);
                }
                else
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Expecting upgrade request.");

                    channel.Close();
                }
            }