Skip to content

Instantly share code, notes, and snippets.

@ctacke
Last active June 22, 2018 17:07
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ctacke/71c017716d758aa8328c70e50c0c3e8d to your computer and use it in GitHub Desktop.
Save ctacke/71c017716d758aa8328c70e50c0c3e8d to your computer and use it in GitHub Desktop.
A simple HTTP server for helping unit and integration testing of REST clients
using System;
using System.Net;
using System.Text;
using System.Threading;
namespace OpenNETCF.Test
{
public sealed class SimpleServer : IDisposable
{
private readonly HttpListener m_listener = new HttpListener();
private readonly Func<HttpListenerRequest, string> m_getMethod;
private readonly Func<HttpListenerRequest, string> m_postMethod;
private readonly Func<HttpListenerRequest, string> m_putMethod;
private readonly Func<HttpListenerRequest, string> m_deleteMethod;
public SimpleServer(
string prefix,
Func<HttpListenerRequest, string> getMethod = null,
Func<HttpListenerRequest, string> postMethod = null,
Func<HttpListenerRequest, string> putMethod = null,
Func<HttpListenerRequest, string> deleteMethod = null)
{
// TODO: at least one method is probably required (to be of any use, anyway)
m_getMethod = getMethod;
m_postMethod = postMethod;
m_putMethod = putMethod;
m_deleteMethod = deleteMethod;
m_listener.Prefixes.Add(prefix);
m_listener.Start();
}
public void Dispose()
{
this.Stop();
}
public void Start()
{
ThreadPool.QueueUserWorkItem((o) =>
{
try
{
while (m_listener.IsListening)
{
ThreadPool.QueueUserWorkItem((c) =>
{
var context = c as HttpListenerContext;
string result;
try
{
// what's the incoming verb?
switch (context.Request.HttpMethod)
{
case "GET":
if (m_getMethod == null) return;
result = m_getMethod(context.Request);
break;
case "POST":
if (m_postMethod == null) return;
result = m_postMethod(context.Request);
break;
case "PUT":
if (m_putMethod == null) return;
result = m_putMethod(context.Request);
break;
case "DELETE":
if (m_deleteMethod == null) return;
result = m_deleteMethod(context.Request);
break;
default:
throw new NotSupportedException(string.Format("HTTP verb {0} not supported", context.Request.HttpMethod));
}
var encodedResult = Encoding.UTF8.GetBytes(result);
context.Response.ContentLength64 = encodedResult.Length;
context.Response.OutputStream.Write(encodedResult, 0, encodedResult.Length);
}
finally
{
context.Response.OutputStream.Close();
}
}, m_listener.GetContext());
}
}
catch (HttpListenerException)
{
// this often happens during Disposal - just ignore it
}
});
}
public void Stop()
{
m_listener.Stop();
m_listener.Close();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment