public HttpsNetworkSession(HttpsNetworkServer server) : base(server) { Cache = server.Cache; NetworkRequest = new HttpNetworkRequest(); NetworkResponse = new HttpNetworkResponse(); }
protected override void OnReceivedResponseError(HttpNetworkResponse response, String error) { // Cancel timeout check timer _timer?.Change(Timeout.Infinite, Timeout.Infinite); SetResultError(error); }
protected override void OnReceivedResponse(HttpNetworkResponse response) { // Cancel timeout check timer _timer?.Change(Timeout.Infinite, Timeout.Infinite); SetResultValue(response); }
private static Boolean Handler(NetworkFileCache cache, String key, Byte[] value, TimeSpan timespan) { HttpNetworkResponse header = new HttpNetworkResponse(); header.SetBegin(200); header.SetContentType(Path.GetExtension(key)); header.SetHeader("Cache-Control", $"max-age={timespan.Seconds}"); header.SetBody(value); return(cache.Add(key, header.Cache.Data, timespan)); }
protected override void OnReceivedResponseError(HttpNetworkResponse response, String error) { // Check for WebSocket handshaked status if (webSocketNetwork.WsHandshaked) { OnError(new SocketError()); return; } base.OnReceivedResponseError(response, error); }
protected override void OnReceivedResponse(HttpNetworkResponse response) { // Check for WebSocket handshaked status if (webSocketNetwork.WsHandshaked) { // Prepare receive frame from the remaining request body String body = NetworkRequest.Body; Byte[] data = Encoding.UTF8.GetBytes(body); webSocketNetwork.PrepareReceiveFrame(data, 0, data.Length); return; } base.OnReceivedResponse(response); }
protected override void OnReceivedResponseHeader(HttpNetworkResponse response) { // Check for WebSocket handshaked status if (webSocketNetwork.WsHandshaked) { return; } // Try to perform WebSocket upgrade if (!webSocketNetwork.PerformClientUpgrade(response, Id)) { base.OnReceivedResponseHeader(response); } }
/// <summary> /// Send WebSocket server upgrade response /// </summary> /// <param name="response">WebSocket upgrade HTTP response</param> public virtual void SendResponse(HttpNetworkResponse response) { }
/// <summary> /// Initialize HTTPS client with a given IP endpoint /// </summary> /// <param name="context">SSL context</param> /// <param name="endpoint">IP endpoint</param> public HttpsNetworkClient(SslNetworkContext context, IPEndPoint endpoint) : base(context, endpoint) { NetworkRequest = new HttpNetworkRequest(); NetworkResponse = new HttpNetworkResponse(); }
/// <summary> /// Handle WebSocket client connected notification /// </summary> /// <param name="response">WebSocket upgrade HTTP response</param> public virtual void OnWsConnected(HttpNetworkResponse response) { }
/// <summary> /// Handle HTTP response received notification /// </summary> /// <remarks>Notification is called when HTTP response was received from the server.</remarks> /// <param name="response">HTTP response</param> protected virtual void OnReceivedResponse(HttpNetworkResponse response) { }
/// <summary> /// Send the HTTP response (synchronous) /// </summary> /// <param name="response">HTTP response</param> /// <returns>Size of sent data</returns> public Int64 SendResponse(HttpNetworkResponse response) { return(Send(response.Cache.Data, response.Cache.Offset, response.Cache.Size)); }
/// <summary> /// Send the HTTP response (asynchronous) /// </summary> /// <param name="response">HTTP response</param> /// <returns>'true' if the current HTTP response was successfully sent, 'false' if the session is not connected</returns> public Boolean SendResponseAsync(HttpNetworkResponse response) { return(SendAsync(response.Cache.Data, response.Cache.Offset, response.Cache.Size)); }
/// <summary> /// Perform WebSocket server upgrade /// </summary> /// <param name="request">WebSocket upgrade HTTP request</param> /// <param name="response">WebSocket upgrade HTTP response</param> /// <returns>'true' if the WebSocket was successfully upgrade, 'false' if the WebSocket was not upgrade</returns> public Boolean PerformServerUpgrade(HttpNetworkRequest request, HttpNetworkResponse response) { if (request.Method != "GET") { return(false); } Boolean error = false; Boolean connection = false; Boolean upgrade = false; Boolean wsKey = false; Boolean wsVersion = false; String accept = ""; // Validate WebSocket handshake headers for (Int32 i = 0; i < request.Headers; ++i) { Tuple <String, String> header = request.Header(i); String key = header.Item1; String value = header.Item2; if (key == "Connection") { if (value != "Upgrade" && value != "keep-alive, Upgrade") { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Connection' header value must be 'Upgrade' or 'keep-alive, Upgrade'", 400); break; } connection = true; } else if (key == "Upgrade") { if (value != "websocket") { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Upgrade' header value must be 'websocket'", 400); break; } upgrade = true; } else if (key == "Sec-WebSocket-Key") { if (String.IsNullOrEmpty(value)) { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Sec-WebSocket-Key' header value must be non empty", 400); break; } // Calculate the original WebSocket hash String wskey = value + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; Byte[] wshash; using (SHA1Managed sha1 = new SHA1Managed()) { wshash = sha1.ComputeHash(Encoding.UTF8.GetBytes(wskey)); } accept = Convert.ToBase64String(wshash); wsKey = true; } else if (key == "Sec-WebSocket-Version") { if (value != "13") { error = true; response.MakeErrorResponse("Invalid WebSocket handshaked request: 'Sec-WebSocket-Version' header value must be '13'", 400); break; } wsVersion = true; } } // Filter out non WebSocket handshake requests if (!connection && !upgrade && !wsKey && !wsVersion) { return(false); } // Failed to perform WebSocket handshake if (!connection || !upgrade || !wsKey || !wsVersion) { if (!error) { response.MakeErrorResponse("Invalid WebSocket response", 400); } _wsHandler.SendResponse(response); return(false); } // Prepare WebSocket upgrade success response response.Clear(); response.SetBegin(101); response.SetHeader("Connection", "Upgrade"); response.SetHeader("Upgrade", "websocket"); response.SetHeader("Sec-WebSocket-Accept", accept); response.SetBody(); // Validate WebSocket upgrade request and response if (!_wsHandler.OnWsConnecting(request, response)) { return(false); } // Send WebSocket upgrade response _wsHandler.SendResponse(response); // WebSocket successfully handshaked! WsHandshaked = true; Array.Fill(WsSendMask, (Byte)0); _wsHandler.OnWsConnected(request); return(true); }
/// <summary> /// Perform WebSocket client upgrade /// </summary> /// <param name="response">WebSocket upgrade HTTP response</param> /// <param name="id">WebSocket client Id</param> /// <returns>'true' if the WebSocket was successfully upgrade, 'false' if the WebSocket was not upgrade</returns> public Boolean PerformClientUpgrade(HttpNetworkResponse response, Guid id) { if (response.Status != 101) { return(false); } Boolean error = false; Boolean accept = false; Boolean connection = false; Boolean upgrade = false; // Validate WebSocket handshake headers for (Int32 i = 0; i < response.Headers; ++i) { Tuple <String, String> header = response.Header(i); String key = header.Item1; String value = header.Item2; if (key == "Connection") { if (value != "Upgrade") { error = true; _wsHandler.OnWsError("Invalid WebSocket handshaked response: 'Connection' header value must be 'Upgrade'"); break; } connection = true; } else if (key == "Upgrade") { if (value != "websocket") { error = true; _wsHandler.OnWsError("Invalid WebSocket handshaked response: 'Upgrade' header value must be 'websocket'"); break; } upgrade = true; } else if (key == "Sec-WebSocket-Accept") { // Calculate the original WebSocket hash String wskey = Convert.ToBase64String(Encoding.UTF8.GetBytes(id.ToString())) + "258EAFA5-E914-47DA-95CA-C5AB0DC85B11"; String wshash; using (SHA1Managed sha1 = new SHA1Managed()) { wshash = Encoding.UTF8.GetString(sha1.ComputeHash(Encoding.UTF8.GetBytes(wskey))); } // Get the received WebSocket hash wskey = Encoding.UTF8.GetString(Convert.FromBase64String(value)); // Compare original and received hashes if (String.Compare(wskey, wshash, StringComparison.InvariantCulture) != 0) { error = true; _wsHandler.OnWsError("Invalid WebSocket handshaked response: 'Sec-WebSocket-Accept' value validation failed"); break; } accept = true; } } // Failed to perform WebSocket handshake if (!accept || !connection || !upgrade) { if (!error) { _wsHandler.OnWsError("Invalid WebSocket response"); } return(false); } // WebSocket successfully handshaked! WsHandshaked = true; IRandom random = RandomUtils.Create(); random.NextBytes(WsSendMask); _wsHandler.OnWsConnected(response); return(true); }
private void SetResultValue(HttpNetworkResponse response) { NetworkResponse = new HttpNetworkResponse(); _tcs.SetResult(response); NetworkRequest.Clear(); }
/// <summary> /// Send WebSocket server upgrade response /// </summary> /// <param name="response">WebSocket upgrade HTTP response</param> public new virtual void SendResponse(HttpNetworkResponse response) { SendResponseAsync(response); }
/// <summary> /// Handle HTTP response error notification /// </summary> /// <remarks>Notification is called when HTTP response error was received from the server.</remarks> /// <param name="response">HTTP response</param> /// <param name="error">HTTP response error</param> protected virtual void OnReceivedResponseError(HttpNetworkResponse response, String error) { }
/// <summary> /// Handle WebSocket server session validating notification /// </summary> /// <remarks> /// Notification is called when WebSocket client is connecting to the server.You can handle the connection and /// validate WebSocket upgrade HTTP request. /// </remarks> /// <param name="request">WebSocket upgrade HTTP request</param> /// <param name="response">WebSocket upgrade HTTP response</param> /// <returns>return 'true' if the WebSocket update request is valid, 'false' if the WebSocket update request is not valid</returns> public virtual Boolean OnWsConnecting(HttpNetworkRequest request, HttpNetworkResponse response) { return(true); }
/// <summary> /// Initialize HTTPS client with a given IP address and port number /// </summary> /// <param name="context">SSL context</param> /// <param name="address">IP address</param> /// <param name="port">Port number</param> public HttpsNetworkClient(SslNetworkContext context, String address, Int32 port) : base(context, address, port) { NetworkRequest = new HttpNetworkRequest(); NetworkResponse = new HttpNetworkResponse(); }