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); } } }
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); } }); }
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); } } }
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(); }
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); }
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; } } } }
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); }
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); } }); }
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); }