Files
NetworkTest/Server/HttpServer.cs

96 lines
2.7 KiB
C#

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<Data?> _getPackage;
private Action<Data, HttpListenerResponse> _writeResponse;
public HttpServer(Func<Data?> getPackage, Action<Data, HttpListenerResponse> 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)}]";
}
}