Skip to content

Commit

Permalink
Fix OWIN issues, move helper methods to separate class
Browse files Browse the repository at this point in the history
  • Loading branch information
mausch committed Jun 30, 2015
1 parent c0b1bc8 commit 85795ad
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 66 deletions.
1 change: 1 addition & 0 deletions QuartzNetWebConsole/QuartzNetWebConsole.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@
<Compile Include="Controllers\TriggerGroupController.cs" />
<Compile Include="Utils\ISchedulerWrapper.cs" />
<Compile Include="Utils\LimitedList.cs" />
<Compile Include="Utils\Owin.cs" />
<Compile Include="Utils\QueryStringParser.cs" />
<Compile Include="Utils\Response.cs" />
<Compile Include="Utils\SchedulerWrapper.cs" />
Expand Down
67 changes: 1 addition & 66 deletions QuartzNetWebConsole/Setup.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Quartz;
Expand Down Expand Up @@ -43,80 +42,16 @@ static Setup() {
Scheduler = () => { throw new Exception("Define QuartzNetWebConsole.Setup.Scheduler"); };
}

private static Uri GetOwinUri(this IDictionary<string, object> env) {
var headers = (IDictionary<string, string[]>)env["owin.RequestHeaders"];
var scheme = (string)env["owin.RequestScheme"];
var hostAndPort = headers["Host"].First().Split(':');
var host = hostAndPort[0];
var port = hostAndPort.Length > 1 ? int.Parse(hostAndPort[1]) : (scheme == Uri.UriSchemeHttp ? 80 : 443);
var path = (string)env["owin.RequestPathBase"] + (string)env["owin.RequestPath"];
var query = (string)env["owin.RequestQueryString"];

var uriBuilder = new UriBuilder(scheme: scheme, host: host, portNumber: port) {
Path = path,
Query = query,
};

return uriBuilder.Uri;
}

private static Stream GetOwinResponseBody(this IDictionary<string, object> env) {
return (Stream) env["owin.ResponseBody"];
}

private static IDictionary<string, string[]> GetOwinResponseHeaders(this IDictionary<string, object> env) {
return (IDictionary<string, string[]>) env["owin.ResponseHeaders"];
}

private static void SetOwinContentType(this IDictionary<string, object> env, string contentType) {
if (string.IsNullOrEmpty(contentType))
return;
env.GetOwinResponseHeaders()["Content-Type"] = new [] {contentType};
}

private static void SetOwinContentLength(this IDictionary<string, object> env, long length) {
env.GetOwinResponseHeaders()["Content-Length"] = new[] { length.ToString() };
}

private static void SetOwinStatusCode(this IDictionary<string, object> env, int statusCode) {
env["owin.ResponseStatusCode"] = statusCode;
}

public delegate Task AppFunc(IDictionary<string, object> env);

private static AppFunc EvaluateResponse(Response response) {
return env => response.Match(
content: async x => {
env.SetOwinContentType(x.ContentType);
env.SetOwinContentLength(x.Content.Length);
var sw = new StreamWriter(env.GetOwinResponseBody());
await sw.WriteAsync(x.Content);
await sw.FlushAsync();
},
xdoc: async x => {
env.SetOwinContentType(x.ContentType);
var content = x.Content.ToString();
env.SetOwinContentLength(content.Length);
var sw = new StreamWriter(env.GetOwinResponseBody());
await sw.WriteAsync(content);
await sw.FlushAsync();
},
redirect: async x => {
env.SetOwinStatusCode(302);
env.GetOwinResponseHeaders()["Location"] = new [] {x.Location};
await Task.Yield();
});
}

public static Func<AppFunc, AppFunc> Owin(Func<IScheduler> scheduler) {
Setup.Scheduler = scheduler;
return app => env => {
var uri = env.GetOwinUri();
var response =
Routing.Routes
.Where(x => uri.AbsolutePath.Split('.')[0].EndsWith(x.Key, StringComparison.InvariantCultureIgnoreCase))
.Select(r => r.Value(uri))
.Select(EvaluateResponse)
.Select(r => r.Value(uri).EvaluateResponse())
.FirstOrDefault();
return response == null ? app(env) : response(env);
};
Expand Down
74 changes: 74 additions & 0 deletions QuartzNetWebConsole/Utils/Owin.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace QuartzNetWebConsole.Utils {
internal static class Owin {
public static Uri GetOwinUri(this IDictionary<string, object> env) {
var headers = (IDictionary<string, string[]>) env["owin.RequestHeaders"];
var scheme = (string) env["owin.RequestScheme"];
var hostAndPort = headers["Host"].First().Split(':');
var host = hostAndPort[0];
var port = hostAndPort.Length > 1 ? int.Parse(hostAndPort[1]) : (scheme == Uri.UriSchemeHttp ? 80 : 443);
var path = (string) env["owin.RequestPathBase"] + (string) env["owin.RequestPath"];
var query = (string) env["owin.RequestQueryString"];

var uriBuilder = new UriBuilder(scheme: scheme, host: host, portNumber: port) {
Path = path,
Query = query,
};

return uriBuilder.Uri;
}

public static Stream GetOwinResponseBody(this IDictionary<string, object> env) {
return (Stream) env["owin.ResponseBody"];
}

public static IDictionary<string, string[]> GetOwinResponseHeaders(this IDictionary<string, object> env) {
return (IDictionary<string, string[]>) env["owin.ResponseHeaders"];
}

public static void SetOwinContentType(this IDictionary<string, object> env, string contentType, string charset) {
if (string.IsNullOrEmpty(contentType))
throw new ArgumentNullException("contentType");
if (string.IsNullOrEmpty(charset))
throw new ArgumentNullException("charset");
env.GetOwinResponseHeaders()["Content-Type"] = new[] {contentType + ";charset=" + charset};
}

public static void SetOwinContentLength(this IDictionary<string, object> env, long length) {
env.GetOwinResponseHeaders()["Content-Length"] = new[] {length.ToString()};
}

public static void SetOwinStatusCode(this IDictionary<string, object> env, int statusCode) {
env["owin.ResponseStatusCode"] = statusCode;
}

private static readonly Encoding encoding = Encoding.UTF8;

public static Setup.AppFunc EvaluateResponse(this Response response) {
return env => response.Match(
content: async x => {
env.SetOwinContentType(x.ContentType, encoding.BodyName);
var content = Encoding.UTF8.GetBytes(x.Content);
env.SetOwinContentLength(content.Length);
await env.GetOwinResponseBody().WriteAsync(content, 0, content.Length);
},
xdoc: async x => {
var eval = new Response.ContentResponse(content: x.Content.ToString(), contentType: x.ContentType).EvaluateResponse();
await eval(env);
},
redirect: async x => {
env.SetOwinStatusCode(302);
env.GetOwinResponseHeaders()["Location"] = new[] { x.Location };
await Task.Yield();
});
}


}
}

0 comments on commit 85795ad

Please sign in to comment.