Skip to content

Instantly share code, notes, and snippets.

@serialseb
Last active August 29, 2015 14:02
Show Gist options
  • Save serialseb/3d76860a8bf5e58fb373 to your computer and use it in GitHub Desktop.
Save serialseb/3d76860a8bf5e58fb373 to your computer and use it in GitHub Desktop.
owin stuff
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