Skip to content

Instantly share code, notes, and snippets.

@davidwhitney
Created January 12, 2018 15:23
Show Gist options
  • Save davidwhitney/ca076ec432d6112a4a06e1e77d1b6d1a to your computer and use it in GitHub Desktop.
Save davidwhitney/ca076ec432d6112a4a06e1e77d1b6d1a to your computer and use it in GitHub Desktop.
using System;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http;
using System.Web.Http.Routing;
using Microsoft.Owin.Hosting;
using Owin;
namespace WireMockFake
{
public class WebServer
{
private readonly HttpConfiguration _config;
public int Port { get; }
public HttpClient Client { get; }
private IDisposable _server;
public WebServer()
{
Port = FreeTcpPort();
Client = new HttpClient { BaseAddress = new Uri($"http://localhost:{Port}") };
_config = new HttpConfiguration();
}
public WebServer StartServer()
{
_server = WebApp.Start(new StartOptions {Port = Port, Urls = {$"http://localhost:{Port}"}}, appBuilder => appBuilder.UseWebApi(_config));
return this;
}
public void StopServer()
{
_server?.Dispose();
}
public WebServer RespondTo(string url, Func<HttpRequestMessage, HttpRouteData, HttpResponseMessage> withThis = null)
{
withThis = withThis ?? ((message, data) => new HttpResponseMessage(HttpStatusCode.NotFound));
_config.Routes.Add(Guid.NewGuid().ToString(),
new HttpRoute(url, new HttpRouteValueDictionary(), new HttpRouteValueDictionary(),
new HttpRouteValueDictionary(), new CustomRouteHandler(withThis)));
StopServer();
StartServer();
return this;
}
public void Dispose() => StopServer();
private static int FreeTcpPort()
{
var l = new TcpListener(IPAddress.Loopback, 0);
l.Start();
var port = ((IPEndPoint)l.LocalEndpoint).Port;
l.Stop();
return port;
}
public class CustomRouteHandler : HttpMessageHandler
{
private readonly Func<HttpRequestMessage, HttpRouteData, HttpResponseMessage> _responder;
public CustomRouteHandler(Func<HttpRequestMessage, HttpRouteData, HttpResponseMessage> responder)
{
_responder = responder;
}
protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
{
var routeData = request.Properties["MS_HttpRouteData"] as HttpRouteData;
return Task.FromResult(_responder(request, routeData));
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment