/// <summary> /// This method permit to get back the real ip behind a proxy and check the list of banned IP. /// </summary> private bool GetAndCheckForwardedIp(string packet) { var splitPacket = packet.Split(new[] { "\n" }, StringSplitOptions.None); foreach (var packetEach in splitPacket) { if (packetEach != null) { if (!string.IsNullOrEmpty(packetEach)) { if (packetEach.ToLower().Contains("x-forwarded-for: ")) { string newIp = packetEach.ToLower().Replace("x-forwarded-for: ", ""); _ip = newIp; ClassLog.Log("HTTP/HTTPS API - X-Forwarded-For ip of the client is: " + newIp, 7, 2); var checkBanResult = ClassApiBan.FilterCheckIp(_ip); if (!checkBanResult) // Is Banned { return(false); } else { if (!string.IsNullOrEmpty(newIp)) { ClassApiBan.FilterInsertIp(newIp); } return(true); } } } } } return(true); }
/// <summary> /// Handle get request received from client. /// </summary> /// <param name="packet"></param> /// <returns></returns> private async Task HandlePacketHttpAsync(string packet) { long selectedIndex = 0; string selectedHash = string.Empty; if (packet.Contains("=")) { var splitPacket = packet.Split(new[] { "=" }, StringSplitOptions.None); if (!long.TryParse(splitPacket[1], out selectedIndex)) { selectedHash = splitPacket[1]; // Hash } packet = splitPacket[0]; } switch (packet) { case ClassApiHttpRequestEnumeration.GetCoinName: await BuildAndSendHttpPacketAsync(ClassConnectorSetting.CoinName); break; case ClassApiHttpRequestEnumeration.GetCoinMinName: await BuildAndSendHttpPacketAsync(ClassConnectorSetting.CoinNameMin); break; case ClassApiHttpRequestEnumeration.GetCoinMaxSupply: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CoinMaxSupply); break; case ClassApiHttpRequestEnumeration.GetCoinCirculating: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CoinCirculating); break; case ClassApiHttpRequestEnumeration.GetCoinTotalFee: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentTotalFee); break; case ClassApiHttpRequestEnumeration.GetCoinTotalMined: await BuildAndSendHttpPacketAsync("" + (ClassRemoteNodeSync.ListOfBlock.Count * 10)); break; case ClassApiHttpRequestEnumeration.GetCoinBlockchainHeight: await BuildAndSendHttpPacketAsync("" + (ClassRemoteNodeSync.ListOfBlock.Count + 1)); break; case ClassApiHttpRequestEnumeration.GetCoinTotalBlockMined: await BuildAndSendHttpPacketAsync("" + (ClassRemoteNodeSync.ListOfBlock.Count)); break; case ClassApiHttpRequestEnumeration.GetCoinTotalBlockLeft: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentBlockLeft); break; case ClassApiHttpRequestEnumeration.GetCoinNetworkDifficulty: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentDifficulty); break; case ClassApiHttpRequestEnumeration.GetCoinNetworkHashrate: await BuildAndSendHttpPacketAsync(ClassRemoteNodeSync.CurrentHashrate); break; case ClassApiHttpRequestEnumeration.GetCoinBlockPerId: if (selectedIndex > 0) { selectedIndex -= 1; if (ClassRemoteNodeSync.ListOfBlock.Count - 1 >= selectedIndex) { if (ClassRemoteNodeSync.ListOfBlock.ContainsKey((int)selectedIndex)) { var splitBlock = ClassRemoteNodeSync.ListOfBlock[(int)selectedIndex].Split(new[] { "#" }, StringSplitOptions.None); Dictionary <string, string> blockContent = new Dictionary <string, string> { { "block_id", splitBlock[0] }, { "block_hash", splitBlock[1] }, { "block_transaction_hash", splitBlock[2] }, { "block_timestamp_create", splitBlock[3] }, { "block_timestamp_found", splitBlock[4] }, { "block_difficulty", splitBlock[5] }, { "block_reward", splitBlock[6] } }; await BuildAndSendHttpPacketAsync(null, true, blockContent); blockContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinBlockPerHash: if (selectedHash != string.Empty) { int selectedBlockIndex = ClassRemoteNodeSync.ListOfBlockHash.GetBlockIdFromHash(selectedHash); if (selectedBlockIndex != -1) { var splitBlock = ClassRemoteNodeSync.ListOfBlock[selectedBlockIndex].Split(new[] { "#" }, StringSplitOptions.None); Dictionary <string, string> blockContent = new Dictionary <string, string> { { "block_id", splitBlock[0] }, { "block_hash", splitBlock[1] }, { "block_transaction_hash", splitBlock[2] }, { "block_timestamp_create", splitBlock[3] }, { "block_timestamp_found", splitBlock[4] }, { "block_difficulty", splitBlock[5] }, { "block_reward", splitBlock[6] } }; await BuildAndSendHttpPacketAsync(null, true, blockContent); blockContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinTransactionPerId: if (selectedIndex > 0) { selectedIndex -= 1; if (ClassRemoteNodeSync.ListOfTransaction.Count - 1 >= selectedIndex) { if (ClassRemoteNodeSync.ListOfTransaction.ContainsKey(selectedIndex)) { var splitTransaction = ClassRemoteNodeSync.ListOfTransaction.GetTransaction(selectedIndex).Split(new[] { "-" }, StringSplitOptions.None); Dictionary <string, string> transactionContent = new Dictionary <string, string> { { "transaction_id", "" + (selectedIndex + 1) }, { "transaction_id_sender", splitTransaction[0] }, { "transaction_fake_amount", splitTransaction[1] }, { "transaction_fake_fee", splitTransaction[2] }, { "transaction_id_receiver", splitTransaction[3] }, { "transaction_timestamp_sended", splitTransaction[4] }, { "transaction_hash", splitTransaction[5] }, { "transaction_timestamp_received", splitTransaction[6] } }; await BuildAndSendHttpPacketAsync(null, true, transactionContent); transactionContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinTransactionPerHash: if (selectedHash != string.Empty) { long transactionIndex = ClassRemoteNodeSync.ListOfTransactionHash.ContainsKey(selectedHash); if (transactionIndex != -1) { var splitTransaction = ClassRemoteNodeSync.ListOfTransaction.GetTransaction(transactionIndex).Split(new[] { "-" }, StringSplitOptions.None); Dictionary <string, string> transactionContent = new Dictionary <string, string> { { "transaction_id", "" + (transactionIndex + 1) }, { "transaction_id_sender", splitTransaction[0] }, { "transaction_fake_amount", splitTransaction[1] }, { "transaction_fake_fee", splitTransaction[2] }, { "transaction_id_receiver", splitTransaction[3] }, { "transaction_timestamp_sended", splitTransaction[4] }, { "transaction_hash", splitTransaction[5] }, { "transaction_timestamp_received", splitTransaction[6] } }; await BuildAndSendHttpPacketAsync(null, true, transactionContent); transactionContent.Clear(); } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } } else { ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); } break; case ClassApiHttpRequestEnumeration.GetCoinNetworkFullStats: Dictionary <string, string> networkStatsContent = new Dictionary <string, string> { { "coin_name", ClassConnectorSetting.CoinName }, { "coin_min_name", ClassConnectorSetting.CoinNameMin }, { "coin_max_supply", ClassRemoteNodeSync.CoinMaxSupply }, { "coin_circulating", decimal.Parse(ClassRemoteNodeSync.CoinCirculating, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_total_fee", decimal.Parse(ClassRemoteNodeSync.CurrentTotalFee, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_total_mined", (ClassRemoteNodeSync.ListOfBlock.Count * ClassConnectorSetting.ConstantBlockReward).ToString() }, { "coin_blockchain_height", "" + (ClassRemoteNodeSync.ListOfBlock.Count + 1) }, { "coin_total_block_mined", "" + ClassRemoteNodeSync.ListOfBlock.Count }, { "coin_total_block_left", ClassRemoteNodeSync.CurrentBlockLeft }, { "coin_network_difficulty", decimal.Parse(ClassRemoteNodeSync.CurrentDifficulty, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_network_hashrate", decimal.Parse(ClassRemoteNodeSync.CurrentHashrate, NumberStyles.Any, Program.GlobalCultureInfo).ToString() }, { "coin_total_transaction", "" + ClassRemoteNodeSync.ListOfTransaction.Count } }; await BuildAndSendHttpPacketAsync(null, true, networkStatsContent); networkStatsContent.Clear(); break; case ClassApiHttpRequestEnumeration.PacketFavicon: ClassLog.Log("HTTP API - packet received from IP: " + _ip + " - favicon request detected and ignored.", 6, 2); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); break; default: ClassApiBan.FilterInsertInvalidPacket(_ip); await BuildAndSendHttpPacketAsync(ClassApiHttpRequestEnumeration.PacketNotExist); break; } }
/// <summary> /// Start to listen incoming client. /// </summary> /// <returns></returns> public async Task StartHandleClientHttpAsync() { try { _ip = ((IPEndPoint)(_client.Client.RemoteEndPoint)).Address.ToString(); } catch { CloseClientConnection(); return; } var checkBanResult = true; if (_ip != "127.0.0.1") // Do not check localhost ip. { checkBanResult = ClassApiBan.FilterCheckIp(_ip); } int totalWhile = 0; if (checkBanResult) { if (_ip != "127.0.0.1") { ClassApiBan.FilterInsertIp(_ip); } try { while (_clientStatus) { try { byte[] buffer = new byte[ClassConnectorSetting.MaxNetworkPacketSize]; using (NetworkStream clientHttpReader = new NetworkStream(_client.Client)) { using (var bufferedStreamNetwork = new BufferedStream(clientHttpReader, ClassConnectorSetting.MaxNetworkPacketSize)) { int received = await bufferedStreamNetwork.ReadAsync(buffer, 0, buffer.Length); if (received > 0) { string packet = Encoding.UTF8.GetString(buffer, 0, received); try { if (!GetAndCheckForwardedIp(packet)) { break; } } catch { } packet = ClassUtilsNode.GetStringBetween(packet, "GET", "HTTP"); packet = packet.Replace("/", ""); packet = packet.Replace(" ", ""); ClassLog.Log("HTTP API - packet received from IP: " + _ip + " - " + packet, 6, 2); await HandlePacketHttpAsync(packet); break; } else { totalWhile++; } if (totalWhile >= 8) { break; } } } } catch { break; } } } catch { } CloseClientConnection(); } }