Example #1
0
        internal static EngineIOPacket Decode(string Data)
        {
            try
            {
                EngineIOPacket Packet = new EngineIOPacket()
                {
                    Type     = (EngineIOPacketType)Data[0] - '0',
                    IsText   = true,
                    IsBinary = false,
                };

                if (Data.Length > 1)
                {
                    Packet.Data    = Data.Substring(1);
                    Packet.RawData = Encoding.UTF8.GetBytes(Packet.Data);
                }

                return(Packet);
            }
            catch (Exception Exception)
            {
                EngineIOLogger.Error("Packet decoding failed. " + Data, Exception);

                return(CreateErrorPacket(Exception));
            }
        }
Example #2
0
        internal static EngineIOPacket Decode(byte[] RawData)
        {
            try
            {
                Queue <byte>   BufferQueue = new Queue <byte>(RawData);
                EngineIOPacket Packet      = new EngineIOPacket()
                {
                    Type     = (EngineIOPacketType)BufferQueue.Dequeue(),
                    IsText   = false,
                    IsBinary = true,
                };

                if (BufferQueue.Count > 0)
                {
                    Packet.RawData = BufferQueue.ToArray();
                    Packet.Data    = BitConverter.ToString(Packet.RawData);
                }

                return(Packet);
            }
            catch (Exception Exception)
            {
                EngineIOLogger.Error("Packet decoding failed. " + RawData != null ? BitConverter.ToString(RawData) : string.Empty, Exception);

                return(CreateErrorPacket(Exception));
            }
        }
        private void Handshake(string TransportName, WebSocketContext Context)
        {
            void OnError()
            {
                Context.WebSocket.Close(CloseStatusCode.Abnormal, Exceptions.BAD_REQUEST.Message);
            }

            try
            {
                if (EngineIOHttpManager.IsWebSocket(TransportName))
                {
                    Handshake(Context.QueryString["sid"] ?? EngineIOSocketID.Generate(), new EngineIOWebSocket(Context));
                }
                else
                {
                    OnError();
                }
            }
            catch (Exception Exception)
            {
                EngineIOLogger.Error(this, Exception);

                OnError();
            }
        }
Example #4
0
        private void Handshake(string TransportName, HttpListenerRequest Request, HttpListenerResponse Response)
        {
            void OnError()
            {
                EngineIOHttpManager.SendErrorMessage(Request, Response, Exceptions.BAD_REQUEST);
            }

            try
            {
                if (EngineIOHttpManager.IsPolling(TransportName))
                {
                    EngineIOTransport Transport = new EngineIOPolling(Request);
                    Transport.OnRequest(Request, Response);

                    Handshake(EngineIOSocketID.Generate(), Transport);
                }
                else
                {
                    OnError();
                }
            }
            catch (Exception Exception)
            {
                EngineIOLogger.Error(this, Exception);

                OnError();
            }
        }
        private void Verify(WebSocketContext Context, Action <EngineIOException> Callback)
        {
            EngineIOException Return = null;
            bool AllowWebSocket      = false;

            try
            {
                if ((Return = Verify(Context.QueryString, Context.Headers, EngineIOTransportType.websocket)) == null)
                {
                    string SID      = EngineIOHttpManager.GetSID(Context.QueryString);
                    bool   Contains = _Clients.ContainsKey(SID);

                    if (!string.IsNullOrEmpty(SID))
                    {
                        if (Contains && _Clients.TryGetValue(SID, out EngineIOSocket Socket))
                        {
                            if (Socket.Transport is EngineIOPolling && Option.AllowUpgrade && Option.WebSocket && !(Socket.Upgrading || Socket.Upgraded))
                            {
                                if (!(Socket.Upgrading || Socket.Upgraded))
                                {
                                    Socket.UpgradeTransport(new EngineIOWebSocket(Context));
                                    AllowWebSocket = true;
                                }
                                else
                                {
                                    Return = Exceptions.BAD_REQUEST;
                                }
                            }
                            else
                            {
                                Return = Exceptions.BAD_REQUEST;
                            }
                        }
                        else
                        {
                            Return = Exceptions.UNKNOWN_SID;
                        }
                    }
                    else
                    {
                        if (Option.AllowWebSocket != null)
                        {
                            AllowWebSocket = true;
                            Option.AllowWebSocket(Context, Callback);
                        }
                    }
                }
            }
            catch (Exception Exception)
            {
                EngineIOLogger.Error(this, Return = new EngineIOException("Unknown exception", Exception));
            }
            finally
            {
                if (!AllowWebSocket)
                {
                    Callback(Return);
                }
            }
        }
        protected EngineIOTransport OnError(string Message, Exception Description)
        {
            EngineIOException Exception = new EngineIOException(Message, Description);

            EngineIOLogger.Error(this, Exception);
            Emit(Event.ERROR, Exception);

            return(this);
        }
Example #7
0
        private void Verify(HttpListenerRequest Request, Action <EngineIOException> Callback)
        {
            EngineIOException Return = null;
            bool AllowHttpRequest    = false;

            try
            {
                if ((Return = Verify(Request.QueryString, Request.Headers, EngineIOTransportType.polling)) == null)
                {
                    string SID      = EngineIOHttpManager.GetSID(Request.QueryString);
                    bool   Contains = _Clients.ContainsKey(SID);

                    if (string.IsNullOrEmpty(SID) || Contains)
                    {
                        if (Contains && !(_Clients[SID].Transport is EngineIOPolling))
                        {
                            Return = Exceptions.BAD_REQUEST;
                        }
                        else if (EngineIOHttpManager.ParseMethod(Request.HttpMethod) == EngineIOHttpMethod.GET)
                        {
                            if (Option.AllowHttpRequest != null)
                            {
                                AllowHttpRequest = true;
                                Option.AllowHttpRequest(Request, Callback);
                            }
                        }
                        else if (string.IsNullOrEmpty(SID))
                        {
                            Return = Exceptions.BAD_HANDSHAKE_METHOD;
                        }
                    }
                    else
                    {
                        Return = Exceptions.UNKNOWN_SID;
                    }
                }
            }
            catch (Exception Exception)
            {
                EngineIOLogger.Error(this, Return = new EngineIOException("Unknown exception", Exception));
            }
            finally
            {
                if (!AllowHttpRequest)
                {
                    Callback(Return);
                }
            }
        }
        internal EngineIOTransport Send(params EngineIOPacket[] Packets)
        {
            if (Packets != null)
            {
                Writable = false;

                ThreadPool.QueueUserWorkItem((_) =>
                {
                    try
                    {
                        Semaphore.WaitOne();

                        if (ReadyState == EngineIOReadyState.OPEN)
                        {
                            try
                            {
                                foreach (EngineIOPacket Packet in Packets)
                                {
                                    SendInternal(Packet);
                                }
                            }
                            catch (Exception Exception)
                            {
                                EngineIOLogger.Error(this, Exception);
                            }
                        }
                        else
                        {
                            EngineIOLogger.Error(this, new EngineIOException("Transport is not opened. ReadyState : " + ReadyState));
                        }

                        Semaphore.Release();
                        Writable = true;
                    }
                    catch (Exception Exception)
                    {
                        OnError("Transport not sent.", Exception);
                    }
                });
            }

            return(this);
        }
Example #9
0
        private static EngineIOPacket[] Decode(Stream Stream, bool IsBinary)
        {
            List <EngineIOPacket> Result = new List <EngineIOPacket>();
            object Temp = string.Empty;

            try
            {
                if (IsBinary)
                {
                    using (MemoryStream MemoryStream = new MemoryStream())
                    {
                        Stream.CopyTo(MemoryStream);
                        Queue <byte> BufferQueue = new Queue <byte>(MemoryStream.ToArray());

                        if (BufferQueue.Contains(0xff))
                        {
                            while (BufferQueue.Count > 0)
                            {
                                List <byte> RawBuffer = new List <byte>();
                                bool        IsText    = BufferQueue.Dequeue() == 0;

                                StringBuilder Buffer = new StringBuilder();
                                int           Size   = 0;

                                while (BufferQueue.Count > 0)
                                {
                                    byte TempSize = BufferQueue.Dequeue();

                                    if (TempSize < 0xff)
                                    {
                                        Buffer.Append(TempSize);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                Size = int.Parse(Buffer.ToString());
                                Buffer.Clear();

                                for (int i = 0; i < Size; i++)
                                {
                                    RawBuffer.Add(BufferQueue.Dequeue());
                                }

                                if (IsText)
                                {
                                    Result.Add(Decode(Encoding.UTF8.GetString(RawBuffer.ToArray())));
                                }
                                else
                                {
                                    Result.Add(Decode(RawBuffer.ToArray()));
                                }
                            }
                        }
                    }
                }
                else
                {
                    using (StreamReader Reader = new StreamReader(Stream))
                    {
                        string Content = (Temp = Reader.ReadToEnd()).ToString();

                        if (Content.Contains(':'))
                        {
                            while (Content.Length > 0)
                            {
                                StringBuilder Buffer = new StringBuilder();
                                int           Size   = 0;

                                for (int i = 0; i < Content.Length; i++)
                                {
                                    if (Content[i] != ':')
                                    {
                                        Buffer.Append(Content[i]);
                                    }
                                    else
                                    {
                                        break;
                                    }
                                }

                                Size    = int.Parse(Buffer.ToString());
                                Content = Content.Substring(Buffer.Length + 1);
                                Buffer.Clear();

                                for (int i = 0; i < Size; i++)
                                {
                                    Buffer.Append(Content[i]);
                                }

                                Content = Content.Substring(Buffer.Length);
                                string Data = Buffer.ToString();

                                if (Data.StartsWith("b"))
                                {
                                    Result.Add(DecodeBase64String(Data));
                                }
                                else
                                {
                                    Result.Add(Decode(Data));
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception Exception)
            {
                EngineIOLogger.Error("Packet decoding failed. " + Temp, Exception);

                Result.Add(CreateErrorPacket(Exception));
            }

            return(Result.ToArray());
        }
Example #10
0
        internal void UpgradeTransport(EngineIOWebSocket Transport)
        {
            void OnTransportPacket(object Argument)
            {
                EngineIOPacket Packet = Argument as EngineIOPacket;

                if (Packet.Type == EngineIOPacketType.PING)
                {
                    Transport.Send(EngineIOPacket.CreatePongPacket(Packet.Data));
                    Emit(Event.UPGRADING);

                    ResetCheckTimer();
                }
                else
                {
                    Cleanup();

                    if (Packet.Type == EngineIOPacketType.UPGRADE && ReadyState != EngineIOReadyState.CLOSED)
                    {
                        this.Transport.Discard();
                        Upgraded = true;

                        ClearTransport();
                        SetTransport(Transport);

                        Emit(Event.UPGRADE);

                        ResetPingTimer();
                        Flush();

                        if (ReadyState == EngineIOReadyState.CLOSING)
                        {
                            this.Transport.Close(() =>
                            {
                                this.OnClose("Forced close.");
                            });
                        }
                    }
                    else
                    {
                        Transport.Close();
                    }
                }
            }

            void Cleanup()
            {
                Upgrading = false;

                StopCheckTimer();
                StopUpgradeTimer();

                Transport.Off(EngineIOTransport.Event.PACKET, OnTransportPacket);
                Transport.Off(EngineIOTransport.Event.CLOSE, OnTransportClose);
                Transport.Off(EngineIOTransport.Event.ERROR, OnTransportError);
            }

            void OnTransportError(object Exception)
            {
                EngineIOLogger.Error(this, Exception as Exception);

                Cleanup();
                Transport.Close();
            }

            void OnTransportClose()
            {
                OnTransportError(new EngineIOException("Transport closed."));
            }

            void OnClose()
            {
                OnTransportError(new EngineIOException("Socket closed."));
            }

            Upgrading = true;
            StartUpgradeTimer(() =>
            {
                Cleanup();

                if (Transport.ReadyState == EngineIOReadyState.OPEN)
                {
                    Transport.Close();
                }
            });

            Transport.On(EngineIOTransport.Event.PACKET, OnTransportPacket);
            Transport.Once(EngineIOTransport.Event.CLOSE, OnTransportClose);
            Transport.Once(EngineIOTransport.Event.ERROR, OnTransportError);

            Once(Event.CLOSE, OnClose);
        }