/// <summary>
            /// Handles an incoming raw HTTP response.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            private void HandleIncomingResponse(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer data = (ChunkedBuffer)obj;

                if (currentIncoming == null)
                {
                    currentIncoming = new HttpResponse(channel.BufferPool);
                }

                if (currentIncoming.Parse(data.Stream, channel.IsActive))
                {
                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received HTTP Response: Command Line: [{0}], Body Size [{1}]", currentIncoming.CommandLine, currentIncoming.BodySize);
                    }

                    obj             = currentIncoming;
                    currentIncoming = null;
                }
            }
        /// <summary>
        /// Invoked when the channel has sucessfully attached.
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="error"></param>
        /// <param name="promise"></param>
        private void OnAttached(ISockNetChannel channel, Exception error, Promise <ISockNetChannel> promise)
        {
            promise.OnFulfilled = null;

            Pipe.HandleOpened();

            State = RemoteSockNetChannelState.Connected;
        }
Exemple #3
0
        /// <summary>
        /// Installs a per channel module.
        /// </summary>
        /// <param name="channel"></param>
        public void Install(ISockNetChannel channel)
        {
            ISockNetChannelModule module = NewPerChannelModule();

            if (channel.SetAttribute(ModuleName, module, false))
            {
                module.Install(channel);
            }
        }
        /// <summary>
        /// Installs a per channel module.
        /// </summary>
        /// <param name="channel"></param>
        public void Install(ISockNetChannel channel)
        {
            ISockNetChannelModule module = NewPerChannelModule();

            if (channel.SetAttribute(ModuleName, module, false))
            {
                module.Install(channel);
            }
        }
            /// <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();
                }
            }
Exemple #6
0
        /// <summary>
        /// Uninstalls a per channel module.
        /// </summary>
        /// <param name="channel"></param>
        public void Uninstall(ISockNetChannel channel)
        {
            object module;

            if (channel.TryGetAttribute(ModuleName, out module))
            {
                ((ISockNetChannelModule)module).Uninstall(channel);

                channel.RemoveAttribute(ModuleName);
            }
        }
Exemple #7
0
            /// <summary>
            /// Uninstalls this module.
            /// </summary>
            /// <param name="channel"></param>
            public void Uninstall(ISockNetChannel channel)
            {
                channel.Pipe.RemoveIncoming <HttpRequest>(HandleHandshake);
                channel.Pipe.RemoveIncoming <object>(HandleIncomingFrames);
                channel.Pipe.RemoveOutgoing <object>(HandleOutgoingFrames);

                if (channel.HasModule(httpModule))
                {
                    channel.RemoveModule(httpModule);
                }
            }
        /// <summary>
        /// Uninstalls a per channel module.
        /// </summary>
        /// <param name="channel"></param>
        public void Uninstall(ISockNetChannel channel)
        {
            object module;

            if (channel.TryGetAttribute(ModuleName, out module))
            {
                ((ISockNetChannelModule)module).Uninstall(channel);

                channel.RemoveAttribute(ModuleName);
            }
        }
            /// <summary>
            /// Handles an incomming raw Gds message.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            public void HandleIncoming(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is ChunkedBuffer))
                {
                    return;
                }

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

                try
                {
                    GdsFrame frame = GdsFrame.ParseFrame(stream.Stream, channel.BufferPool);

                    if (combineChunks)
                    {
                        if (frame.IsComplete)
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);

                            obj          = chunkedFrame;
                            chunkedFrame = null;
                        }
                        else
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);
                        }
                    }
                    else
                    {
                        obj = frame;
                    }

                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received Gds message. Body Size: {0}, Type: {1}, IsComplete: {2}", frame.Body.AvailableBytesToRead, Enum.GetName(typeof(GdsFrame.GdsFrameType), frame.Type), frame.IsComplete);
                    }
                }
                catch (EndOfStreamException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (Exception e)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to parse Gds message", e);
                }
            }
            /// <summary>
            /// Handles WebSocketFrame(s) and translates them into raw frames.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleOutgoingFrames(ISockNetChannel channel, ref object data)
            {
                if (!(data is WebSocketFrame))
                {
                    return;
                }

                WebSocketFrame webSocketFrame = (WebSocketFrame)data;
                ChunkedBuffer  buffer         = new ChunkedBuffer(channel.BufferPool);

                webSocketFrame.Write(buffer.Stream);
                data = buffer;
            }
Exemple #11
0
        /// <summary>
        /// Clones this pipe and sets the given parent.
        /// </summary>
        /// <param name="newParent"></param>
        /// <param name="includeModules"></param>
        /// <returns></returns>
        public SockNetChannelPipe Clone(ISockNetChannel newParent, bool includeModules = true)
        {
            SockNetChannelPipe newPipe = new SockNetChannelPipe(newParent);

            lock (openedHandlers)
            {
                foreach (OnOpenedDelegate del in openedHandlers)
                {
                    if (includeModules || !(del.Target is ISockNetChannelModule))
                    {
                        newPipe.openedHandlers.AddLast(del);
                    }
                }
            }

            lock (closedHandlers)
            {
                foreach (OnClosedDelegate del in closedHandlers)
                {
                    if (includeModules || !(del.Target is ISockNetChannelModule))
                    {
                        newPipe.closedHandlers.AddLast(del);
                    }
                }
            }

            lock (incomingHandlers)
            {
                foreach (IDelegateReference del in incomingHandlers)
                {
                    if (includeModules || !(del.Delegate.Target is ISockNetChannelModule))
                    {
                        newPipe.incomingHandlers.AddLast(del);
                    }
                }
            }

            lock (outgoingHandlers)
            {
                foreach (IDelegateReference del in outgoingHandlers)
                {
                    if (includeModules || !(del.Delegate.Target is ISockNetChannelModule))
                    {
                        newPipe.outgoingHandlers.AddLast(del);
                    }
                }
            }

            return(newPipe);
        }
            /// <summary>
            /// Handles an outgoing HttpRequest and converts it to a raw buffer.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            public void HandleOutgoing(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is GdsFrame))
                {
                    return;
                }

                GdsFrame      gdsFrame = (GdsFrame)obj;
                ChunkedBuffer buffer   = new ChunkedBuffer(channel.BufferPool);

                gdsFrame.Write(buffer.Stream);

                gdsFrame.Dispose();

                obj = buffer;
            }
Exemple #13
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>
            /// Invoked on channel connect.
            /// </summary>
            /// <param name="channel"></param>
            public void OnConnected(ISockNetChannel channel)
            {
                SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Sending WebSocket upgrade request.");

                channel.Pipe.AddIncomingLast <HttpResponse>(HandleHandshake);

                HttpRequest request = new HttpRequest(channel.BufferPool)
                {
                    Action  = "GET",
                    Path    = path,
                    Version = "HTTP/1.1"
                };

                request.Header["Host"]       = hostname;
                request.Header["Upgrade"]    = "websocket";
                request.Header["Connection"] = "Upgrade";
                request.Header[WebSocketUtil.WebSocketKeyHeader]     = secKey;
                request.Header[WebSocketUtil.WebSocketVersionHeader] = "13";

                channel.Send(request);
            }
            /// <summary>
            /// Handles an outgoing HttpRequest and converts it to a raw buffer.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            private void HandleOutgoingRequest(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is HttpRequest))
                {
                    return;
                }

                HttpRequest data = (HttpRequest)obj;

                if (SockNetLogger.DebugEnabled)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Sending HTTP Request: Command Line: [{0}], Body Size [{1}]", data.CommandLine, data.BodySize);
                }

                ChunkedBuffer buffer = new ChunkedBuffer(channel.BufferPool);

                data.Write(buffer.Stream);

                data.Dispose();

                obj = buffer;
            }
            /// <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();
                }
            }
 public void Install(ISockNetChannel channel)
 {
     channel.Pipe.AddIncomingFirst <object>(HandleIncoming);
     channel.Pipe.AddOutgoingLast <object>(HandleOutgoing);
 }
            /// <summary>
            /// Updates the given chunked frame with a new frame.
            /// </summary>
            /// <param name="frame"></param>
            private static void UpdateChunk(ref GdsFrame chunkedFrame, GdsFrame frame, ISockNetChannel channel)
            {
                if (chunkedFrame == null)
                {
                    chunkedFrame = frame;  // set initial frame
                }
                else
                {
                    if (frame.Type == GdsFrame.GdsFrameType.Ping || frame.Type == GdsFrame.GdsFrameType.Pong || frame.Type == GdsFrame.GdsFrameType.Close)
                    {
                        chunkedFrame = frame;
                    }

                    GdsFrame.GdsFrameType type = chunkedFrame.Type;

                    ChunkedBuffer body = null;

                    if (frame.Type == GdsFrame.GdsFrameType.BodyOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.HeadersOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        body = new ChunkedBuffer(channel.BufferPool);
                        chunkedFrame.Body.DrainToStreamSync(body.Stream).Close();
                        frame.Body.DrainToStreamSync(body.Stream).Close();
                    }

                    Dictionary <string, byte[]> headers = null;

                    if (frame.Type == GdsFrame.GdsFrameType.HeadersOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.BodyOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        headers = new Dictionary <string, byte[]>(StringComparer.OrdinalIgnoreCase);
                        foreach (KeyValuePair <string, byte[]> kvp in chunkedFrame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                        foreach (KeyValuePair <string, byte[]> kvp in frame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                    }

                    chunkedFrame.Dispose();
                    frame.Dispose();

                    chunkedFrame = GdsFrame.NewContentFrame(frame.StreamId, headers, false, body, frame.IsComplete);
                }
            }
            /// <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();
                }
            }
Exemple #20
0
 /// <summary>
 /// Invoked when there is outgoing data on the given channel.
 /// </summary>
 /// <param name="channel">the channel with the data</param>
 /// <param name="data">the data</param>
 public virtual void OnOutgoingData(ISockNetChannel channel, ref T data)
 {
     // noop
 }
            /// <summary>
            /// Updates the given chunked frame with a new frame.
            /// </summary>
            /// <param name="frame"></param>
            private static void UpdateChunk(ref GdsFrame chunkedFrame, GdsFrame frame, ISockNetChannel channel)
            {
                if (chunkedFrame == null)
                {
                    chunkedFrame = frame;  // set initial frame
                }
                else
                {
                    if (frame.Type == GdsFrame.GdsFrameType.Ping || frame.Type == GdsFrame.GdsFrameType.Pong || frame.Type == GdsFrame.GdsFrameType.Close)
                    {
                        chunkedFrame = frame;
                    }

                    GdsFrame.GdsFrameType type = chunkedFrame.Type;

                    ChunkedBuffer body = null;

                    if (frame.Type == GdsFrame.GdsFrameType.BodyOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.HeadersOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        body = new ChunkedBuffer(channel.BufferPool);
                        chunkedFrame.Body.DrainToStreamSync(body.Stream).Close();
                        frame.Body.DrainToStreamSync(body.Stream).Close();
                    }

                    Dictionary<string, byte[]> headers = null;

                    if (frame.Type == GdsFrame.GdsFrameType.HeadersOnly || frame.Type == GdsFrame.GdsFrameType.Full)
                    {
                        if (type == GdsFrame.GdsFrameType.BodyOnly)
                        {
                            type = GdsFrame.GdsFrameType.Full;
                        }

                        headers = new Dictionary<string, byte[]>(StringComparer.OrdinalIgnoreCase);
                        foreach (KeyValuePair<string, byte[]> kvp in chunkedFrame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                        foreach (KeyValuePair<string, byte[]> kvp in frame.Headers)
                        {
                            headers[kvp.Key] = kvp.Value;
                        }
                    }

                    chunkedFrame.Dispose();
                    frame.Dispose();

                    chunkedFrame = GdsFrame.NewContentFrame(frame.StreamId, headers, false, body, frame.IsComplete);
                }
            }
 /// <summary>
 /// Installs this module.
 /// </summary>
 /// <param name="channel"></param>
 public void Install(ISockNetChannel channel)
 {
     channel.AddModule(httpModule);
     channel.Pipe.AddOpenedLast(OnConnected);
 }
            /// <summary>
            /// Uninstalls this module.
            /// </summary>
            /// <param name="channel"></param>
            public void Uninstall(ISockNetChannel channel)
            {
                channel.Pipe.RemoveIncoming<HttpResponse>(HandleHandshake);
                channel.Pipe.RemoveIncoming<object>(HandleIncomingFrames);
                channel.Pipe.RemoveOutgoing<object>(HandleOutgoingFrames);
                channel.Pipe.RemoveOpened(OnConnected);

                if (channel.HasModule(httpModule))
                {
                    channel.RemoveModule(httpModule);
                }
            }
Exemple #24
0
            /// <summary>
            /// Installs this module.
            /// </summary>
            /// <param name="channel"></param>
            public void Install(ISockNetChannel channel)
            {
                channel.AddModule(httpModule);

                channel.Pipe.AddIncomingLast <HttpRequest>(HandleHandshake);
            }
            /// <summary>
            /// Handles an incomming raw Gds message.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            public void HandleIncoming(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is ChunkedBuffer))
                {
                    return;
                }

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

                try
                {
                    GdsFrame frame = GdsFrame.ParseFrame(stream.Stream, channel.BufferPool);

                    if (combineChunks)
                    {
                        if (frame.IsComplete)
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);

                            obj = chunkedFrame;
                            chunkedFrame = null;
                        }
                        else
                        {
                            UpdateChunk(ref chunkedFrame, frame, channel);
                        }
                    }
                    else
                    {
                        obj = frame;
                    }

                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received Gds message. Body Size: {0}, Type: {1}, IsComplete: {2}", frame.Body.AvailableBytesToRead, Enum.GetName(typeof(GdsFrame.GdsFrameType), frame.Type), frame.IsComplete);
                    }
                }
                catch (EndOfStreamException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (ArgumentOutOfRangeException)
                {
                    // frame isn't done
                    stream.ReadPosition = startingPosition;
                }
                catch (Exception e)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.ERROR, this, "Unable to parse Gds message", e);
                }
            }
Exemple #26
0
 /// <summary>
 /// Invoked when the channel opens.
 /// </summary>
 /// <param name="channel">the channel that opened</param>
 public virtual void OnOpen(ISockNetChannel channel)
 {
     // noop
 }
 /// <summary>
 /// Installs this module.
 /// </summary>
 /// <param name="channel"></param>
 public void Install(ISockNetChannel channel)
 {
     channel.AddModule(httpModule);
     channel.Pipe.AddOpenedLast(OnConnected);
 }
            /// <summary>
            /// Handles an outgoing HttpResponse and converts it into a raw buffer.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            private void HandleOutgoingResponse(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is HttpResponse))
                {
                    return;
                }

                HttpResponse data = (HttpResponse)obj;

                if (SockNetLogger.DebugEnabled)
                {
                    SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Sending HTTP Response: Command Line: [{0}], Body Size [{1}]", data.CommandLine, data.BodySize);
                }

                ChunkedBuffer buffer = new ChunkedBuffer(channel.BufferPool);

                data.Write(buffer.Stream);

                data.Dispose();

                obj = buffer;
            }
            /// <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();
                }
            }
Exemple #30
0
 /// <summary>
 /// Invoked when the channel closes.
 /// </summary>
 /// <param name="channel">the channel that closed</param>
 public virtual void OnClose(ISockNetChannel channel)
 {
     // noop
 }
 public void Uninstall(ISockNetChannel channel)
 {
     channel.Pipe.RemoveIncoming <object>(HandleIncoming);
     channel.Pipe.RemoveOutgoing <object>(HandleOutgoing);
 }
            /// <summary>
            /// Handles an outgoing HttpRequest and converts it to a raw buffer.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            public void HandleOutgoing(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is GdsFrame))
                {
                    return;
                }

                GdsFrame gdsFrame = (GdsFrame)obj;
                ChunkedBuffer buffer = new ChunkedBuffer(channel.BufferPool);
                gdsFrame.Write(buffer.Stream);

                gdsFrame.Dispose();

                obj = buffer;
            }
            /// <summary>
            /// Installs this module.
            /// </summary>
            /// <param name="channel"></param>
            public void Install(ISockNetChannel channel)
            {
                channel.AddModule(httpModule);

                channel.Pipe.AddIncomingLast<HttpRequest>(HandleHandshake);
            }
 public void Install(ISockNetChannel channel)
 {
     channel.Pipe.AddIncomingFirst<object>(HandleIncoming);
     channel.Pipe.AddOutgoingLast<object>(HandleOutgoing);
 }
            /// <summary>
            /// Invoked on channel connect.
            /// </summary>
            /// <param name="channel"></param>
            public void OnConnected(ISockNetChannel channel)
            {
                SockNetLogger.Log(SockNetLogger.LogLevel.INFO, this, "Sending WebSocket upgrade request.");

                channel.Pipe.AddIncomingLast<HttpResponse>(HandleHandshake);

                HttpRequest request = new HttpRequest(channel.BufferPool)
                {
                    Action = "GET",
                    Path = path,
                    Version = "HTTP/1.1"
                };
                request.Header["Host"] = hostname;
                request.Header["Upgrade"] = "websocket";
                request.Header["Connection"] = "Upgrade";
                request.Header[WebSocketUtil.WebSocketKeyHeader] = secKey;
                request.Header[WebSocketUtil.WebSocketVersionHeader] = "13";

                channel.Send(request);
            }
 public void Uninstall(ISockNetChannel channel)
 {
     channel.Pipe.RemoveIncoming<object>(HandleIncoming);
     channel.Pipe.RemoveOutgoing<object>(HandleOutgoing);
 }
            /// <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();
                }
            }
Exemple #38
0
 /// <summary>
 /// Creates a pipe with the given parent.
 /// </summary>
 /// <param name="parent"></param>
 public SockNetChannelPipe(ISockNetChannel parent)
 {
     this.parent = parent;
 }
            /// <summary>
            /// Handles WebSocketFrame(s) and translates them into raw frames.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="request"></param>
            private void HandleOutgoingFrames(ISockNetChannel channel, ref object data)
            {
                if (!(data is WebSocketFrame))
                {
                    return;
                }

                WebSocketFrame webSocketFrame = (WebSocketFrame)data;
                ChunkedBuffer buffer = new ChunkedBuffer(channel.BufferPool);
                webSocketFrame.Write(buffer.Stream);
                data = buffer;
            }
            /// <summary>
            /// Handles an incomming raw HTTP response.
            /// </summary>
            /// <param name="channel"></param>
            /// <param name="obj"></param>
            private void HandleIncomingRequest(ISockNetChannel channel, ref object obj)
            {
                if (!(obj is ChunkedBuffer))
                {
                    return;
                }

                ChunkedBuffer data = (ChunkedBuffer)obj;

                if (currentIncoming == null)
                {
                    currentIncoming = new HttpRequest(channel.BufferPool);
                }

                if (currentIncoming.Parse(data.Stream, channel.IsActive))
                {
                    if (SockNetLogger.DebugEnabled)
                    {
                        SockNetLogger.Log(SockNetLogger.LogLevel.DEBUG, this, "Received HTTP Request: Command Line: [{0}], Body Size [{1}]", currentIncoming.CommandLine, currentIncoming.BodySize);
                    }

                    obj = currentIncoming;
                    currentIncoming = null;
                }
            }