Created
July 10, 2015 20:09
-
-
Save anonymous/7c55b290c6f862cf1492 to your computer and use it in GitHub Desktop.
SimpleServer - makes echo testing from .NET unit tests easier
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
using System.IO; | |
// modified from RestSharp unit tests https://github.com/restsharp/RestSharp/blob/master/RestSharp.IntegrationTests/Helpers/SimpleServer.cs | |
namespace UnitTesting | |
{ | |
using System; | |
using System.Net; | |
using System.Security; | |
using System.Threading; | |
/// <summary> | |
/// Simple echo handler | |
/// </summary> | |
/// <remarks>via https://github.com/restsharp/RestSharp/blob/master/RestSharp.IntegrationTests/Helpers/SimpleServer.cs </remarks> | |
public class SimpleServer : IDisposable | |
{ | |
private readonly HttpListener listener; | |
private readonly Action<HttpListenerContext> handler; | |
private Thread thread; | |
private SimpleServer(HttpListener listener, Action<HttpListenerContext> handler) | |
{ | |
this.listener = listener; | |
this.handler = handler; | |
} | |
/// <summary> | |
/// Simple echo handler | |
/// <example>Usage: <code> | |
/// using (SimpleServer.Create(SimpleServer.ECHO_URL)) { /* make an http post to same url, get back what you sent */ } | |
/// </code></example> | |
/// </summary> | |
/// <remarks>via https://github.com/restsharp/RestSharp/blob/master/RestSharp.IntegrationTests/Helpers/SimpleServer.cs </remarks> | |
/// <param name="url"></param> | |
/// <param name="authenticationSchemes"></param> | |
/// <returns></returns> | |
public static SimpleServer Create( | |
string url, | |
AuthenticationSchemes authenticationSchemes = AuthenticationSchemes.Anonymous) | |
{ | |
return Create(url, context => EchoHandler(context), authenticationSchemes); | |
} | |
/// <summary> | |
/// Simple echo handler | |
/// <example>Usage: <code> | |
/// using (SimpleServer.Create(SimpleServer.ECHO_URL, SimpleServer.QueryStringBasedContentAndContentTypeHandler)) { /* make an http post to same url, get back what you sent */ } | |
/// </code></example> | |
/// </summary> | |
/// <remarks>via https://github.com/restsharp/RestSharp/blob/master/RestSharp.IntegrationTests/Helpers/SimpleServer.cs </remarks> | |
/// <param name="url"></param> | |
/// <param name="handler"></param> | |
/// <param name="authenticationSchemes"></param> | |
/// <returns></returns> | |
public static SimpleServer Create( | |
string url, | |
Action<HttpListenerContext> handler, | |
AuthenticationSchemes authenticationSchemes = AuthenticationSchemes.Anonymous) | |
{ | |
var listener = new HttpListener { Prefixes = { url }, AuthenticationSchemes = authenticationSchemes }; | |
var server = new SimpleServer(listener, handler); | |
server.Start(); | |
return server; | |
} | |
public void Start() | |
{ | |
if (this.listener.IsListening) | |
{ | |
return; | |
} | |
this.listener.Start(); | |
this.thread = new Thread(() => { | |
var context = this.listener.GetContext(); | |
if(this.handler != null) this.handler(context); | |
context.Response.Close(); | |
}) { Name = "WebServer" }; | |
this.thread.Start(); | |
} | |
public void Dispose() | |
{ | |
try | |
{ | |
this.thread.Abort(); | |
} | |
catch (ThreadStateException threadStateException) | |
{ | |
Console.WriteLine("Issue aborting thread - {0}.", threadStateException.Message); | |
} | |
catch (SecurityException securityException) | |
{ | |
Console.WriteLine("Issue aborting thread - {0}.", securityException.Message); | |
} | |
if (this.listener.IsListening) | |
{ | |
try | |
{ | |
this.listener.Stop(); | |
} | |
catch (ObjectDisposedException objectDisposedException) | |
{ | |
Console.WriteLine("Issue stopping listener - {0}", objectDisposedException.Message); | |
} | |
} | |
this.listener.Close(); | |
} | |
/// <summary> | |
/// Handler helper that takes the content type, content from the querystring ("ct" and "c", respectively) | |
/// </summary> | |
/// <param name="obj"></param> | |
public static void QueryStringBasedContentAndContentTypeHandler(HttpListenerContext obj) | |
{ | |
QueryStringBasedContentAndContentTypeHandler(obj, "ct", "c", 200); | |
} | |
/// <summary> | |
/// Handler helper that takes the content type/content from the querystring | |
/// </summary> | |
/// <param name="obj"></param> | |
/// <param name="paramContentType"></param> | |
/// <param name="paramContent"></param> | |
/// <param name="statusCode"></param> | |
public static void QueryStringBasedContentAndContentTypeHandler(HttpListenerContext obj, string paramContentType, string paramContent, int statusCode) | |
{ | |
var contentType = obj.Request.QueryString[paramContentType]; | |
if( ! string.IsNullOrWhiteSpace(contentType) ) obj.Response.ContentType = contentType; | |
var content = obj.Request.QueryString[paramContent]; | |
if(null != content) | |
using(var sw = new StreamWriter(obj.Response.OutputStream)) | |
sw.Write(content); | |
obj.Response.StatusCode = statusCode; | |
} | |
/// <summary> | |
/// Handler helper that just dumps what was sent | |
/// </summary> | |
/// <param name="obj"></param> | |
/// <param name="statusCode"></param> | |
/// <param name="contentIsNthAcceptType">Which accept type should be used as the content type?</param> | |
public static void EchoHandler(HttpListenerContext obj, int statusCode = 200, int contentIsNthAcceptType = 0) | |
{ | |
obj.Response.ContentType = obj.Request.AcceptTypes == null || obj.Request.AcceptTypes.Length == 0 ? obj.Request.ContentType : obj.Request.AcceptTypes[contentIsNthAcceptType]; | |
string content = null; | |
using (var sr = new StreamReader(obj.Request.InputStream)) content = sr.ReadToEnd(); | |
if (null != content) | |
using (var sw = new StreamWriter(obj.Response.OutputStream)) | |
sw.Write(content); | |
obj.Response.StatusCode = statusCode; | |
} | |
/// <summary> | |
/// Can use to return what you sent, for testing. | |
/// </summary> | |
public const string ECHO_URL = "http://localhost:8080/"; | |
/// <summary> | |
/// Returns what you sent, for testing. If Fiddler is enabled, this will be an echo service. | |
/// </summary> | |
public const string FIDDLER_ECHO_URL = "http://localhost:8888/"; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
d'oh