using System; using System.Net; using System.Text; using System.Text.Json; using System.Threading; using System.Threading.Tasks; using Domain; using Domain.Dto; namespace NetworkTest; public class HttpServer : IServer { private readonly HttpListener _listener; private readonly string _url; private CancellationTokenSource _cts = new CancellationTokenSource(); private Func _getPackage; private Action _writeResponse; public HttpServer(Func getPackage, Action writeResponse, string url = "http://*:5555/") { _getPackage = getPackage; _writeResponse = writeResponse; _url = url; _listener = new HttpListener(); _listener.Prefixes.Add(_url); } public void Start() { _cts = new CancellationTokenSource(); _listener.Start(); Task.Run(() => ListenAsync(_cts.Token)); } public void Stop() { _cts.Cancel(); _listener.Stop(); } private async Task ListenAsync(CancellationToken token) { while (!token.IsCancellationRequested) { try { var context = await _listener.GetContextAsync(); _ = Task.Run(() => HandleRequest(context)); } catch (HttpListenerException) { break; } catch (ObjectDisposedException) { break; } } } private void HandleRequest(HttpListenerContext context) { if (context.Request.Url?.AbsolutePath.Equals("/fetchpackage", StringComparison.OrdinalIgnoreCase) == true) { var data = _getPackage(); if (data != null) { _writeResponse(data, context.Response); } else { var responseText = JsonSerializer.Serialize(new { error = "Data not found" }); context.Response.StatusCode = 404; byte[] buffer = Encoding.UTF8.GetBytes(responseText); context.Response.ContentType = "application/json"; context.Response.ContentLength64 = buffer.Length; context.Response.OutputStream.Write(buffer, 0, buffer.Length); } } else { context.Response.StatusCode = 404; byte[] buffer = Encoding.UTF8.GetBytes("Not Found"); context.Response.OutputStream.Write(buffer, 0, buffer.Length); } context.Response.OutputStream.Close(); } public override string ToString() { return $"HTTP: [{string.Join(", ", _listener.Prefixes)}]"; } }