73 lines
2.1 KiB
C#
73 lines
2.1 KiB
C#
using System.Net;
|
|
using System.Net.Sockets;
|
|
using System.Text;
|
|
|
|
namespace Recordingtest.EngineBridge.IntegrationTests;
|
|
|
|
public sealed class FakeBridgeServer : IDisposable
|
|
{
|
|
public Dictionary<string, string> Responses { get; } = new();
|
|
public TimeSpan ResponseDelay { get; set; } = TimeSpan.Zero;
|
|
|
|
private readonly HttpListener _listener;
|
|
private readonly Thread _thread;
|
|
private volatile bool _stop;
|
|
|
|
public int Port { get; }
|
|
public string BaseUrl => $"http://localhost:{Port}";
|
|
|
|
public FakeBridgeServer()
|
|
{
|
|
Port = FindFreePort();
|
|
_listener = new HttpListener();
|
|
_listener.Prefixes.Add($"http://localhost:{Port}/");
|
|
_listener.Start();
|
|
_thread = new Thread(Loop) { IsBackground = true };
|
|
_thread.Start();
|
|
}
|
|
|
|
private static int FindFreePort()
|
|
{
|
|
var l = new TcpListener(IPAddress.Loopback, 0);
|
|
l.Start();
|
|
var p = ((IPEndPoint)l.LocalEndpoint).Port;
|
|
l.Stop();
|
|
return p;
|
|
}
|
|
|
|
private void Loop()
|
|
{
|
|
while (!_stop && _listener.IsListening)
|
|
{
|
|
HttpListenerContext ctx;
|
|
try { ctx = _listener.GetContext(); }
|
|
catch { return; }
|
|
try
|
|
{
|
|
if (ResponseDelay > TimeSpan.Zero) Thread.Sleep(ResponseDelay);
|
|
var path = ctx.Request.Url?.AbsolutePath ?? "/";
|
|
if (Responses.TryGetValue(path, out var body))
|
|
{
|
|
var bytes = Encoding.UTF8.GetBytes(body);
|
|
ctx.Response.StatusCode = 200;
|
|
ctx.Response.ContentType = "application/json";
|
|
ctx.Response.OutputStream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
else
|
|
{
|
|
ctx.Response.StatusCode = 404;
|
|
}
|
|
ctx.Response.OutputStream.Close();
|
|
}
|
|
catch { try { ctx.Response.Abort(); } catch { } }
|
|
}
|
|
}
|
|
|
|
public void Dispose()
|
|
{
|
|
_stop = true;
|
|
try { _listener.Stop(); } catch { }
|
|
try { _listener.Close(); } catch { }
|
|
}
|
|
}
|