Пример #1
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 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();
            }
        }
        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);
                }
            }
        }
Пример #4
0
        internal EngineIOWebSocket(WebSocketContext Context)
        {
            Semaphore = new Semaphore(0, 1);
            Semaphore.Release();

            Client            = Context.WebSocket;
            Client.OnMessage += OnWebSocketMessage;
            Client.OnClose   += OnWebSocketClose;
            Client.OnError   += OnWebSocketError;
            Client.Log.Output = EngineIOLogger.WebSocket;

            ForceBase64 = EngineIOHttpManager.IsBase64Forced(Context.QueryString);
            Writable    = true;
        }
 private void OnWebSocket(WebSocketContext Context)
 {
     Verify(Context, (Exception) =>
     {
         if (Exception == null)
         {
             Handshake(EngineIOHttpManager.GetTransport(Context.QueryString), Context);
         }
         else
         {
             Context.WebSocket.Close(CloseStatusCode.Abnormal, Exception.Message);
         }
     });
 }
Пример #6
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);
                }
            }
        }
Пример #7
0
        public EngineIOPolling(HttpListenerRequest Request)
        {
            Origin      = EngineIOHttpManager.GetOrigin(Request.Headers);
            ForceBase64 = int.TryParse(Request.QueryString["b64"]?.Trim() ?? string.Empty, out int Base64) && Base64 > 0;

            ConnectionTimer = new Timer(1)
            {
                AutoReset = true
            };
            ConnectionTimer.Elapsed += (_, __) =>
            {
                if (PollResponse?.IsDisconnected ?? false)
                {
                    OnPollRequestClose(new SocketException());
                }
            };

            ConnectionTimer.Start();
        }
Пример #8
0
        internal override EngineIOTransport OnRequest(HttpListenerRequest Request, HttpListenerResponse Response)
        {
            EngineIOHttpMethod Method = EngineIOHttpManager.ParseMethod(Request.HttpMethod);

            if (Method == EngineIOHttpMethod.GET)
            {
                OnPollRequest(Request, Response);
            }
            else if (Method == EngineIOHttpMethod.POST)
            {
                OnDataRequest(Request, Response);
            }
            else
            {
                CloseResponse(Response);
            }

            return(this);
        }
Пример #9
0
        private void OnOpen()
        {
            ReadyState            = EngineIOReadyState.OPEN;
            PriorWebsocketSuccess = Transport is EngineIOWebSocket;

            Emit(Event.OPEN);
            Flush();

            if (ReadyState == EngineIOReadyState.OPEN && Option.Upgrade && Option.WebSocket && Transport is EngineIOPolling)
            {
                foreach (string Upgrade in Handshake.Upgrades)
                {
                    if (EngineIOHttpManager.IsWebSocket(Upgrade))
                    {
                        Probe();
                        break;
                    }
                }
            }
        }
Пример #10
0
        private WebHeaderCollection SetHeaders(WebHeaderCollection Headers)
        {
            string UserAgent = EngineIOHttpManager.GetUserAgent(Headers);

            if (UserAgent.Contains(";MSIE") || UserAgent.Contains("Trident/"))
            {
                Headers["X-XSS-Protection"] = "0";
            }

            if (!string.IsNullOrEmpty(Origin))
            {
                Headers["Access-Control-Allow-Credentials"] = "true";
                Headers["Access-Control-Allow-Origin"]      = Origin;
            }
            else
            {
                Headers["Access-Control-Allow-Origin"] = "*";
            }

            Emit(Event.HEADERS, Headers);
            return(Headers);
        }
Пример #11
0
        private void OnHttpRequest(object sender, HttpRequestEventArgs e)
        {
            Verify(e.Request, (Exception) =>
            {
                if (Exception == null)
                {
                    string SID = EngineIOHttpManager.GetSID(e.Request.QueryString);

                    if (_Clients.TryGetValue(SID, out EngineIOSocket Client))
                    {
                        Client.Transport.OnRequest(e.Request, e.Response);
                    }
                    else
                    {
                        Handshake(EngineIOHttpManager.GetTransport(e.Request.QueryString), e.Request, e.Response);
                    }
                }
                else
                {
                    EngineIOHttpManager.SendErrorMessage(e.Request, e.Response, Exception);
                }
            });
        }
Пример #12
0
        private EngineIOException Verify(NameValueCollection QueryString, NameValueCollection Headers, EngineIOTransportType ExpectedTransportType)
        {
            EngineIOException Exception = Exceptions.UNKNOWN_TRANSPORT;

            if (EngineIOHttpManager.GetTransport(QueryString).Equals(ExpectedTransportType.ToString()))
            {
                bool IsPolling   = EngineIOHttpManager.IsPolling(QueryString) && Option.Polling;
                bool IsWebSocket = EngineIOHttpManager.IsWebSocket(QueryString) && Option.WebSocket;

                if (IsPolling || IsWebSocket)
                {
                    if (EngineIOHttpManager.IsValidHeader(EngineIOHttpManager.GetOrigin(Headers)))
                    {
                        Exception = null;
                    }
                    else
                    {
                        Exception = Exceptions.BAD_REQUEST;
                    }
                }
            }

            return(Exception);
        }