internal Task HandleClient() { _remoteEndPoint = _client.Client.RemoteEndPoint; _logger.LogDebug($"Start client socket on port {_remoteEndPoint}"); var session = Guid.NewGuid().ToString(); _connectionSession = _middleware.GetSession(session); _connectionSession.Client = _client; _client.ReceiveTimeout = 0; try { using (var networkStream = _client.GetStream()) { byte[] receiveBuffer = new byte[_client.ReceiveBufferSize]; while (_client.Connected) { _logger.LogDebug("Waiting for more data from the client...."); // This is blocking and will wait for data to come from the client. // var bytesRead = networkStream.Read(receiveBuffer, 0, _client.ReceiveBufferSize);; lock (_connectionSession) { if (bytesRead == 0) { _logger.LogDebug( "**************************** REQUEST RECEIVED but no data available *************************"); break; } var content = receiveBuffer.AsSpan(0, bytesRead).ToArray(); if (_connectionSession.IsVerified) { _logger.LogDebug("Already in a verified state.."); var encryptionResult = DecryptData(content, _connectionSession); content = encryptionResult; } //_logger.LogTrace($"Read {Encoding.UTF8.GetString(content)}"); var ms = new MemoryStream(content); var sr = new StreamReader(ms); var request = sr.ReadLine(); var tokens = request.Split(' '); if (tokens.Length != 3) { _middleware.TerminateSession(session); throw new Exception("Invalid HTTP request line"); } var method = tokens[0].ToUpper(); var url = tokens[1].Trim('/'); _logger.LogDebug($"Request {method} on path {url}"); string line; Dictionary <string, string> httpHeaders = new Dictionary <string, string>(); while ((line = sr.ReadLine()) != null) { if (String.IsNullOrEmpty(line)) { break; } var lineSplit = line.Split(":", StringSplitOptions.RemoveEmptyEntries); if (lineSplit.Length != 2) { _logger.LogWarning($"Invalid header format in {line}"); continue; } httpHeaders.Add(lineSplit[0].ToLower(), lineSplit[1]); } var contentLengthHeader = httpHeaders.ContainsKey("content-length"); var contentLenght = 0; if (contentLengthHeader) { contentLenght = Convert.ToInt32( httpHeaders.Single(a => a.Key == "content-length").Value); } var datLen = content.Length; var data = content.AsSpan(datLen - contentLenght, contentLenght).ToArray(); var result = _middleware.Invoke(session, url, method, data, _session); var response = GetHttpResponse("HTTP/1.1", result.Item1, result.Item2, DateTime.Now); _logger.LogTrace($"Writing {Encoding.UTF8.GetString(response)}"); if (_connectionSession.IsVerified && !_connectionSession.SkipFirstEncryption) { response = EncryptData(response, _connectionSession); networkStream.Write(response, 0, response.Length); networkStream.Flush(); } else { networkStream.Write(response, 0, response.Length); networkStream.Flush(); if (_connectionSession.SkipFirstEncryption) { _connectionSession.SkipFirstEncryption = false; } } _logger.LogDebug( "**************************** REQUEST DONE *************************"); } } _middleware.TerminateSession(session); _client.Close(); _client.Dispose(); _httpServer.ConnectionClosed(this); } } catch (Exception e) { _logger.LogError(e, "Error occured in http server"); _middleware.TerminateSession(session); } return(Task.CompletedTask); }
private Task HandleClient(TcpClient tcpClient, CancellationTokenSource token) { return(Task.Run(async() => { var session = Guid.NewGuid().ToString(); var connectionSession = _middleware.GetSession(session); connectionSession.Socket = tcpClient.Client; tcpClient.ReceiveTimeout = TimeSpan.FromSeconds(1).Milliseconds; try { using (var networkStream = tcpClient.GetStream()) { byte[] receiveBuffer = new byte[tcpClient.ReceiveBufferSize]; while (true) { _logger.LogDebug("Waiting for more data from the client...."); // This is blocking and will wait for data to come from the client. // var bytesRead = await networkStream.ReadAsync(receiveBuffer, 0, tcpClient.ReceiveBufferSize); lock (connectionSession) { if (bytesRead == 0) { _logger.LogDebug( "**************************** REQUEST RECEIVED but not data available *************************"); tcpClient.Close(); break; } var content = receiveBuffer.AsSpan(0, bytesRead).ToArray(); if (connectionSession.IsVerified) { _logger.LogDebug("Already in a verified state.."); var encryptionResult = DecryptData(content, connectionSession); content = encryptionResult; } _logger.LogTrace($"Read {Encoding.UTF8.GetString(content)}"); var ms = new MemoryStream(content); var sr = new StreamReader(ms); var request = sr.ReadLine(); var tokens = request.Split(' '); if (tokens.Length != 3) { _middleware.TerminateSession(session); throw new Exception("Invalid HTTP request line"); } var method = tokens[0].ToUpper(); var url = tokens[1].Trim('/'); var version = tokens[2]; string line; Dictionary <string, string> httpHeaders = new Dictionary <string, string>(); while ((line = sr.ReadLine()) != null) { if (String.IsNullOrEmpty(line)) { break; } var lineSplit = line.Split(":", StringSplitOptions.RemoveEmptyEntries); if (lineSplit.Length != 2) { _logger.LogWarning($"Invalid header format in {line}"); continue; } httpHeaders.Add(lineSplit[0].ToLower(), lineSplit[1]); } var contentLengthHeader = httpHeaders.ContainsKey("content-length"); var contentLenght = 0; if (contentLengthHeader) { contentLenght = Convert.ToInt32( httpHeaders.Single(a => a.Key == "content-length").Value); } var datLen = content.Length; var data = content.AsSpan(datLen - contentLenght, contentLenght).ToArray(); var result = _middleware.Invoke(session, url, method, data); var response = GetHttpResponse("HTTP/1.1", result.Item1, result.Item2); _logger.LogTrace($"Writing {Encoding.UTF8.GetString(response)}"); if (connectionSession.IsVerified && !connectionSession.SkipFirstEncryption) { response = EncryptData(response, connectionSession); networkStream.Write(response, 0, response.Length); networkStream.Flush(); } else { networkStream.Write(response, 0, response.Length); networkStream.Flush(); if (connectionSession.SkipFirstEncryption) { connectionSession.SkipFirstEncryption = false; } } _logger.LogDebug( "**************************** REQUEST DONE *************************"); } } _middleware.TerminateSession(session); } } catch (Exception e) { _middleware.TerminateSession(session); } }, token.Token)); }