Last active
August 29, 2015 14:02
-
-
Save serialseb/3d76860a8bf5e58fb373 to your computer and use it in GitHub Desktop.
owin stuff
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; | |
using System.Collections.Generic; | |
using System.IO; | |
using System.Linq; | |
using System.Text; | |
using System.Threading.Tasks; | |
using Nancy; | |
using Nancy.Owin; | |
using Nowin; | |
namespace OwinFx | |
{ | |
using Env = IDictionary<string, object>; | |
using AppFunc = Func<IDictionary<string, object>, Task>; | |
using MidFunc = Func<Func<IDictionary<string, object>, Task>, Func<IDictionary<string, object>, Task>>; | |
class Program | |
{ | |
static string QuoteOfTheDay = "Masak harus galau , antara berhati hati dengan biasa saja"; | |
static void Main(string[] args) | |
{ | |
var myMiddleware = new List<MidFunc>(); | |
Action<MidFunc> appBuilder = myMiddleware.Add; | |
appBuilder.UseNotFound() | |
.UseVanity() | |
.UseUriDispatch(new Dictionary<string, Action<Action<MidFunc>>> | |
{ | |
{ "/hello", _=>_.UseMessage("hello") }, | |
{ "/motd", _=>_.UseMessage(QuoteOfTheDay) }, | |
{ "/nancy", _=>_.UseNancy() }, | |
{ "/nancy2", _=> _.UseNancy() | |
} | |
}); | |
new ServerBuilder().SetPort(8080) | |
.SetOwinApp( | |
myMiddleware.Build(null).Invoke) | |
.Start(); | |
Console.ReadLine(); | |
} | |
} | |
public static class MyBuilderExtensions | |
{ | |
public static Action<MidFunc> UseUriDispatch(this Action<MidFunc> builder, Dictionary<string, Action<Action<MidFunc>>> maps) | |
{ | |
builder(next => async env=> | |
{ | |
await new MyUriDispatcher(maps).Dispatch(env); | |
await next(env); | |
}); | |
return builder; | |
} | |
public static Action<MidFunc> UseMessage(this Action<MidFunc> builder, string message) | |
{ | |
// add middleware to something | |
builder(next => new MessageWriterApp(message).Invoke); | |
return builder; | |
} | |
public static Action<MidFunc> UseNancy(this Action<MidFunc> appBuilder) | |
{ | |
MidFunc func = next => new NancyOwinHost(_ => Task.FromResult(0), new NancyOptions()).Invoke; | |
appBuilder(func); | |
return appBuilder; | |
} | |
public static AppFunc Build(this IEnumerable<MidFunc> array, AppFunc appFunc) | |
{ | |
return array.Aggregate(appFunc, | |
(current, next) => next(current)); | |
} | |
public static Action<MidFunc> UseNotFound(this Action<MidFunc> builder) | |
{ | |
builder(next => new NotFoundMiddleware(next).Invoke); | |
return builder; | |
} | |
public static Action<MidFunc> UseVanity(this Action<MidFunc> appBuilder) | |
{ | |
appBuilder(next => new VanityHeaderMiddleware(next).Invoke); | |
return appBuilder; | |
} | |
} | |
public class NotFoundMiddleware | |
{ | |
readonly AppFunc _next; | |
public NotFoundMiddleware(AppFunc next) | |
{ | |
_next = next; | |
} | |
public async Task Invoke(Env env) | |
{ | |
await _next(env); | |
if ((int)env["owin.ResponseStatusCode"] != 404) return; | |
var headers = (IDictionary<string, string[]>)env["owin.ResponseHeaders"]; | |
if (headers["Content-Length"].Any()) return; | |
var responseStream = (Stream)env["owin.ResponseBody"]; | |
var buffer = Encoding.UTF8.GetBytes("Not found"); | |
await responseStream.WriteAsync(buffer, 0, buffer.Length); | |
} | |
} | |
public class VanityHeaderMiddleware | |
{ | |
readonly AppFunc _next; | |
public VanityHeaderMiddleware(AppFunc next) | |
{ | |
_next = next; | |
} | |
public Task Invoke(Env env) | |
{ | |
var headers = (IDictionary<string, string[]>)env["owin.ResponseHeaders"]; | |
headers["X-PoweredByOwin"] = new[] { "1.0" }; | |
return _next(env); | |
} | |
} | |
public class MyNancyCodeModule : NancyModule | |
{ | |
public MyNancyCodeModule() | |
{ | |
Get["/nancy"] = ctx => "nancy"; | |
} | |
} | |
public class MyUriDispatcher | |
{ | |
readonly Dictionary<string, Action<Action<MidFunc>>> _uriMaps; | |
public MyUriDispatcher(Dictionary<string, Action<Action<MidFunc>>> uriMaps) | |
{ | |
_uriMaps = uriMaps; | |
} | |
public Task Dispatch(IDictionary<string, object> env) | |
{ | |
var requestUri = (string)env["owin.RequestPath"]; | |
return DispatchToAppFuncOr(requestUri, env, Write404); | |
} | |
Task DispatchToAppFuncOr(string requestUri, | |
IDictionary<string, object> env, | |
Func<MidFunc> notFound) | |
{ | |
Action<Action<MidFunc>> mappedEntry; | |
if (!_uriMaps.TryGetValue(requestUri, out mappedEntry)) | |
{ | |
return Execute404(); | |
} | |
var foundMiddleware = GetRegisteredMiddelware(mappedEntry); | |
AppFunc myFinalApp = foundMiddleware(null); | |
return myFinalApp(env); | |
} | |
static MidFunc GetRegisteredMiddelware(Action<Action<MidFunc>> mappedEntry) | |
{ | |
MidFunc foundMiddleware = null; | |
Action<MidFunc> builder = value => { foundMiddleware = value; }; | |
mappedEntry(builder); | |
return foundMiddleware; | |
} | |
Task Execute404() | |
{ | |
return Task.FromResult(0); | |
} | |
MidFunc Write404() | |
{ | |
return next => async env => { env["owin.ResponseStatusCode"] = 404; }; | |
} | |
} | |
public class MessageWriterApp | |
{ | |
readonly int _statusCode; | |
readonly string _text; | |
public MessageWriterApp(string text, int statusCode = 200) | |
{ | |
_text = text; | |
_statusCode = statusCode; | |
} | |
public async Task Invoke(IDictionary<string, object> env) | |
{ | |
var responseStream = (Stream)env["owin.ResponseBody"]; | |
env["owin.ResponseStatusCode"] = _statusCode; | |
var buffer = Encoding.UTF8.GetBytes(_text); | |
await responseStream.WriteAsync(buffer, 0, buffer.Length); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment