public void Invoke(CallParameters call, Action<ResultParameters, Exception> callback) { var request = new RequestEnvironment(call.Environment); var theScheduler = scheduler ?? request.Scheduler; var oldBody = call.Body; if (oldBody != null) { call.Body = RescheduleBody(theScheduler, call.Body); } wrapped( call, (result, error) => theScheduler.Post(() => { result.Body = RescheduleBody(theScheduler, result.Body); callback(result, error); })); // result(status, headers, RescheduleBody(theScheduler, body))), // e => // theScheduler.Post(() => // error(e))); }
public Task<ResultParameters> Invoke(CallParameters call) { var request = new Request(call); var response = new Response(); if (request.Path == "/") { response.Status = "200 OK"; response.ContentType = "text/html"; response.StartAsync().Then(resp1 => { resp1.Write("<h1>Sample.App</h1>"); resp1.Write("<p><a href='{0}/wilson/'>Wilson</a></p>", request.PathBase); resp1.Write("<p><a href='{0}/wilsonasync/'>Wilson (async)</a></p>", request.PathBase); resp1.Write("<p><a href='{0}/nancy/'>Nancy</a></p>", request.PathBase); resp1.Write("<p><a href='{0}/fileupload'>File Upload</a></p>", request.PathBase); resp1.End(); }); return response.ResultTask; } else { response.StatusCode = 404; return response.EndAsync(); } }
public Task<ResultParameters> Invoke(CallParameters call) { var request = new Request(call); var response = new Response() { ContentType = "text/html", }; var wilson = "left - right\r\n123456789012\r\nhello world!\r\n"; response.StartAsync().Then(resp1 => { var href = "?flip=left"; if (request.Query["flip"] == "left") { wilson = wilson.Split(new[] {System.Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries).Select(line => new string(line.Reverse().ToArray())).Aggregate("", (agg, line) => agg + line + System.Environment.NewLine); href = "?flip=right"; } return TimerLoop(350, () => resp1.Write("<title>Hutchtastic</title>"), () => resp1.Write("<pre>"), () => resp1.Write(wilson), () => resp1.Write("</pre>"), () => { if (request.Query["flip"] == "crash") { throw new ApplicationException("Wilson crashed!"); } }, () => resp1.Write("<p><a href='" + href + "'>flip!</a></p>"), () => resp1.Write("<p><a href='?flip=crash'>crash!</a></p>"), () => resp1.End()); }).Catch(errorInfo => { response.Error(errorInfo.Exception); return errorInfo.Handled(); }); return response.ResultTask; }
public Task<ResultParameters> Invoke(CallParameters call) { var request = new Request(call); var response = new Response {ContentType = "text/html"}; var wilson = "left - right\r\n123456789012\r\nhello world!\r\n"; var href = "?flip=left"; if (request.Query["flip"] == "left") { wilson = wilson.Split(new[] {System.Environment.NewLine}, StringSplitOptions.RemoveEmptyEntries).Select(line => new string(line.Reverse().ToArray())).Aggregate("", (agg, line) => agg + line + System.Environment.NewLine); href = "?flip=right"; } response.Write("<title>Wilson</title>"); response.Write("<pre>"); response.Write(wilson); response.Write("</pre>"); if (request.Query["flip"] == "crash") { throw new ApplicationException("Wilson crashed!"); } response.Write("<p><a href='" + href + "'>flip!</a></p>"); response.Write("<p><a href='?flip=crash'>crash!</a></p>"); return response.EndAsync(); }
public Task<ResultParameters> Invoke(CallParameters call) { pathInfo = call.Environment[OwinConstants.RequestPath].ToString(); if (pathInfo.StartsWith("/")) { pathInfo = pathInfo.Substring(1); } if (pathInfo.Contains("..")) { return Fail(Forbidden, "Forbidden").Invoke(call); } path = Path.Combine(root ?? string.Empty, pathInfo); if (!File.Exists(path)) { return Fail(NotFound, "File not found: " + pathInfo).Invoke(call); } try { return Serve(call); } catch (UnauthorizedAccessException) { return Fail(Forbidden, "Forbidden").Invoke(call); } }
public Task<ResultParameters> Invoke(CallParameters call) { var path = call.Environment[OwinConstants.RequestPath].ToString(); if (urls.Any(path.StartsWith)) { return fileServer.Invoke(call); } else { return app.Invoke(call); } }
public void Invoke(CallParameters call, Action<ResultParameters, Exception> callback) { var path = call.Environment[OwinConstants.RequestPath].ToString(); if (urls.Any(path.StartsWith)) { fileServer.Invoke(call, callback); } else { app.Invoke(call, callback); } }
Task<ResultParameters> Raw(CallParameters call) { ResultParameters result = new ResultParameters(); result.Status = 200; result.Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) { { "Content-Type", new[] { "text/plain" } } }; result.Properties = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); result.Body = stream => { byte[] body = Encoding.UTF8.GetBytes("Hello from lowest-level code"); stream.Write(body, 0, body.Length); return TaskHelpers.Completed(); }; return TaskHelpers.FromResult(result); }
public static Task<ResultParameters> Call(CallParameters call) { return TaskHelpers.FromResult(new ResultParameters { Status = 404, Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) { {"Content-Type", new[] {"text/html"}} }, Body = output => { output.Write(Body.Array, Body.Offset, Body.Count); return TaskHelpers.Completed(); }, Properties = new Dictionary<string, object>() }); }
public static CallParameters CreateCallParams( string method = "GET", string path = "/", string pathBase = "", string queryString = "", string scheme = "http", string version = "1.0") { var cp = new CallParameters(); cp.Environment = new Dictionary<string, object>() { {"owin.RequestMethod", method}, {"owin.RequestPath", path}, {"owin.RequestPathBase", pathBase}, {"owin.RequestQueryString", queryString}, {"owin.RequestScheme", scheme}, {"owin.Version", version} }; return cp; }
public static Task<ResultParameters> Execute(CallParameters call) { return TaskHelpers.FromResult(new ResultParameters { Status = 200, Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) { {"Content-Type", new[] {"text/plain"}} }, Body = output => { using (var writer = new StreamWriter(output)) { writer.Write("Welcome to the machine"); } return TaskHelpers.Completed(); }, Properties = new Dictionary<string, object>(), }); }
public void OnRequest(HttpRequestHead head, IDataProducer body, IHttpResponseDelegate response) { var request = new CallParameters(); request.Environment = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); var requestWrapper = new RequestEnvironment(request.Environment); if (context != null) foreach (var kv in context) request.Environment[kv.Key] = kv.Value; if (head.Headers == null) request.Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase); else request.Headers = head.Headers.ToDictionary(kv => kv.Key, kv => new[] { kv.Value }, StringComparer.OrdinalIgnoreCase); requestWrapper.Method = head.Method ?? ""; requestWrapper.Path = head.Path ?? ""; requestWrapper.PathBase = ""; requestWrapper.QueryString = head.QueryString ?? ""; requestWrapper.Scheme = "http"; // XXX requestWrapper.Version = "1.0"; if (body == null) request.Body = null; /* else request.Body = (write, end, cancellationToken) => { var d = body.Connect(new DataConsumer( write, end, () => end(null))); cancellationToken.Register(d.Dispose); }; */ // TODO: Request body stream appDelegate(request) .Then(result => HandleResponse(response, result)) .Catch(errorInfo => HandleError(response, errorInfo)); }
public Task<ResultParameters> Call(CallParameters call) { var paths = new Paths(call.Environment); var path = paths.Path; var pathBase = paths.PathBase; var match = _map.FirstOrDefault(m => path.StartsWith(m.Item1)); if (match == null) { // fall-through to default return _app(call); } // Map moves the matched portion of Path into PathBase paths.PathBase = pathBase + match.Item1; paths.Path = path.Substring(match.Item1.Length); return match.Item2.Invoke(call).Then(result => { // Path and PathBase are restored as the call returnss paths.Path = path; paths.PathBase = pathBase; return result; }); }
public Task<ResultParameters> Invoke(CallParameters call) { Call = call; if (OnRequest != null) OnRequest(); return response.EndAsync(); }
public Task<ResultParameters> Main(CallParameters call) { throw new NotImplementedException(); }
static void ErrorPage(CallParameters call, Exception ex, Action<string> write) { // XXX test this more thoroughly on mono, it shouldn't throw NullRef, // but rather, branch gracefully if something comes up null try { var request = new Request(call); var path = request.PathBase + request.Path; var frames = StackFrames(ex); var first = frames.FirstOrDefault(); var location = ""; if (ex.TargetSite != null && ex.TargetSite.DeclaringType != null) { location = ex.TargetSite.DeclaringType.FullName + "." + ex.TargetSite.Name; } else if (first != null) { location = first.Function; } // adapted from Django <djangoproject.com> // Copyright (c) 2005, the Lawrence Journal-World // Used under the modified BSD license: // http://www.xfree86.org/3.3.6/COPYRIGHT2.html#5 write(@" <!DOCTYPE HTML PUBLIC ""-//W3C//DTD HTML 4.01 Transitional//EN"" ""http://www.w3.org/TR/html4/loose.dtd""> <html lang=""en""> <head> <meta http-equiv=""content-type"" content=""text/html; charset=utf-8"" /> <meta name=""robots"" content=""NONE,NOARCHIVE"" /> <title>"); write(h(ex.GetType().Name)); write(@" at "); write(h(path)); write(@"</title> <style type=""text/css""> html * { padding:0; margin:0; } body * { padding:10px 20px; } body * * { padding:0; } body { font:small sans-serif; } body>div { border-bottom:1px solid #ddd; } h1 { font-weight:normal; } h2 { margin-bottom:.8em; } h2 span { font-size:80%; color:#666; font-weight:normal; } h3 { margin:1em 0 .5em 0; } h4 { margin:0 0 .5em 0; font-weight: normal; } table { border:1px solid #ccc; border-collapse: collapse; background:white; } tbody td, tbody th { vertical-align:top; padding:2px 3px; } thead th { padding:1px 6px 1px 3px; background:#fefefe; text-align:left; font-weight:normal; font-size:11px; border:1px solid #ddd; } tbody th { text-align:right; color:#666; padding-right:.5em; } table.vars { margin:5px 0 2px 40px; } table.vars td, table.req td { font-family:monospace; } table td.code { width:100%;} table td.code div { overflow:hidden; } table.source th { color:#666; } table.source td { font-family:monospace; white-space:pre; border-bottom:1px solid #eee; } ul.traceback { list-style-type:none; } ul.traceback li.frame { margin-bottom:1em; } div.context { margin: 10px 0; } div.context ol { padding-left:30px; margin:0 10px; list-style-position: inside; } div.context ol li { font-family:monospace; white-space:pre; color:#666; cursor:pointer; } div.context ol.context-line li { color:black; background-color:#ccc; } div.context ol.context-line li span { float: right; } div.commands { margin-left: 40px; } div.commands a { color:black; text-decoration:none; } #summary { background: #ffc; } #summary h2 { font-weight: normal; color: #666; } #summary ul#quicklinks { list-style-type: none; margin-bottom: 2em; } #summary ul#quicklinks li { float: left; padding: 0 1em; } #summary ul#quicklinks>li+li { border-left: 1px #666 solid; } #explanation { background:#eee; } #template, #template-not-exist { background:#f6f6f6; } #template-not-exist ul { margin: 0 0 0 20px; } #traceback { background:#eee; } #requestinfo { background:#f6f6f6; padding-left:120px; } #summary table { border:none; background:transparent; } #requestinfo h2, #requestinfo h3 { position:relative; margin-left:-100px; } #requestinfo h3 { margin-bottom:-1em; } .error { background: #ffc; } .specific { color:#cc3300; font-weight:bold; } </style> <script type=""text/javascript""> //<!-- function getElementsByClassName(oElm, strTagName, strClassName){ // Written by Jonathan Snook, http://www.snook.ca/jon; // Add-ons by Robert Nyman, http://www.robertnyman.com var arrElements = (strTagName == ""*"" && document.all)? document.all : oElm.getElementsByTagName(strTagName); var arrReturnElements = new Array(); strClassName = strClassName.replace(/\-/g, ""\\-""); var oRegExp = new RegExp(""(^|\\s)"" + strClassName + ""(\\s|$$)""); var oElement; for(var i=0; i<arrElements.length; i++){ oElement = arrElements[i]; if(oRegExp.test(oElement.className)){ arrReturnElements.push(oElement); } } return (arrReturnElements) } function hideAll(elems) { for (var e = 0; e < elems.length; e++) { elems[e].style.display = 'none'; } } window.onload = function() { hideAll(getElementsByClassName(document, 'table', 'vars')); hideAll(getElementsByClassName(document, 'ol', 'pre-context')); hideAll(getElementsByClassName(document, 'ol', 'post-context')); } function toggle() { for (var i = 0; i < arguments.length; i++) { var e = document.getElementById(arguments[i]); if (e) { e.style.display = e.style.display == 'none' ? 'block' : 'none'; } } return false; } function varToggle(link, id) { toggle('v' + id); var s = link.getElementsByTagName('span')[0]; var uarr = String.fromCharCode(0x25b6); var darr = String.fromCharCode(0x25bc); s.innerHTML = s.innerHTML == uarr ? darr : uarr; return false; } //--> </script> </head> <body> <div id=""summary""> <h1>"); write(h(ex.GetType().Name)); write(@" at "); write(h(path)); write(@"</h1> <h2>"); write(h(ex.Message)); write(@"</h2> <table><tr> <th>.NET</th> <td> "); if (!string.IsNullOrEmpty(location) && !string.IsNullOrEmpty(first.File)) { write(@" <code>"); write(h(location)); write(@"</code>: in <code>"); write(h(first.File)); write(@"</code>, line "); write(h(first.Line)); write(@" "); } else if (!string.IsNullOrEmpty(location)) { write(@" <code>"); write(h(location)); write(@"</code> "); } else { write(@" unknown location "); } write(@" </td> </tr><tr> <th>Web</th> <td><code>"); write(h(request.Method)); write(@" "); write(h(request.Host + path)); write(@" </code></td> </tr></table> <h3>Jump to:</h3> <ul id=""quicklinks""> <li><a href=""#get-info"">GET</a></li> <li><a href=""#post-info"">POST</a></li> <li><a href=""#cookie-info"">Cookies</a></li> <li><a href=""#header-info"">Headers</a></li> <li><a href=""#env-info"">ENV</a></li> </ul> </div> <div id=""traceback""> <h2>Traceback <span>(innermost first)</span></h2> <ul class=""traceback""> "); foreach (var frameIndex in frames.Select((frame, index) => Tuple.Create(frame, index))) { var frame = frameIndex.Item1; var index = frameIndex.Item2; write(@" <li class=""frame""> <code>"); write(h(frame.File)); write(@"</code>: in <code>"); write(h(frame.Function)); write(@"</code> "); if (frame.ContextCode != null) { write(@" <div class=""context"" id=""c{%=h frame.object_id %}""> "); if (frame.PreContextCode != null) { write(@" <ol start="""); write(h(frame.PreContextLine + 1)); write(@""" class=""pre-context"" id=""pre"); write(h(index)); write(@"""> "); foreach (var line in frame.PreContextCode) { write(@" <li onclick=""toggle('pre"); write(h(index)); write(@"', 'post"); write(h(index)); write(@"')"">"); write(h(line)); write(@"</li> "); } write(@" </ol> "); } write(@" <ol start="""); write(h(frame.Line)); write(@""" class=""context-line""> <li onclick=""toggle('pre"); write(h(index)); write(@"', 'post"); write(h(index)); write(@"')"">"); write(h(frame.ContextCode)); write(@"<span>...</span></li></ol> "); if (frame.PostContextCode != null) { write(@" <ol start='"); write(h(frame.Line + 1)); write(@"' class=""post-context"" id=""post"); write(h(index)); write(@"""> "); foreach (var line in frame.PostContextCode) { write(@" <li onclick=""toggle('pre"); write(h(index)); write(@"', 'post"); write(h(index)); write(@"')"">"); write(h(line)); write(@"</li> "); } write(@" </ol> "); } write(@" </div> "); } write(@" </li> "); } write(@" </ul> </div> <div id=""requestinfo""> <h2>Request information</h2> <h3 id=""get-info"">GET</h3> "); if (request.Query.Any()) { write(@" <table class=""req""> <thead> <tr> <th>Variable</th> <th>Value</th> </tr> </thead> <tbody> "); foreach (var kv in request.Query.OrderBy(kv => kv.Key)) { write(@" <tr> <td>"); write(h(kv.Key)); write(@"</td> <td class=""code""><div>"); write(h(kv.Value)); write(@"</div></td> </tr> "); } write(@" </tbody> </table> "); } else { write(@" <p>No GET data.</p> "); } write(@" <h3 id=""post-info"">POST</h3> "); var form = request.ReadForm(); if (form.Any()) { write(@" <table class=""req""> <thead> <tr> <th>Variable</th> <th>Value</th> </tr> </thead> <tbody> "); foreach (var kv in form.OrderBy(kv => kv.Key)) { write(@" <tr> <td>"); write(h(kv.Key)); write(@"</td> <td class=""code""><div>"); write(h(kv.Value)); write(@"</div></td> </tr> "); } write(@" </tbody> </table> "); } else { write(@" <p>No POST data.</p> "); } write(@" <h3 id=""cookie-info"">COOKIES</h3> "); if (request.Cookies.Any()) { write(@" <table class=""req""> <thead> <tr> <th>Variable</th> <th>Value</th> </tr> </thead> <tbody> "); foreach (var kv in request.Cookies.OrderBy(kv => kv.Key)) { write(@" <tr> <td>"); write(h(kv.Key)); write(@"</td> <td class=""code""><div>"); write(h(kv.Value)); write(@"</div></td> </tr> "); } write(@" </tbody> </table> "); } else { write(@" <p>No cookie data.</p> "); } write(@" <h3 id=""cookie-info"">HEADERS</h3> "); if (request.Headers.Any()) { write(@" <table class=""req""> <thead> <tr> <th>Variable</th> <th>Value</th> </tr> </thead> <tbody> "); foreach (var kv in request.Headers.OrderBy(kv => kv.Key)) { write(@" <tr> <td nowrap=""nowrap"">"); write(h(kv.Key)); write(@"</td> <td class=""code""><div>"); foreach (var v in kv.Value) { write(h(v)); write(@"<br/>"); } write(@"</div></td> </tr> "); } write(@" </tbody> </table> "); } else { write(@" <p>No header data.</p> "); } write(@" <h3 id=""env-info"">OWIN ENV</h3> <table class=""req""> <thead> <tr> <th>Variable</th> <th>Value</th> </tr> </thead> <tbody> "); foreach (var kv in call.Environment.OrderBy(kv => kv.Key)) { write(@" <tr> <td>"); write(h(kv.Key)); write(@"</td> <td class=""code""><div>"); write(h(kv.Value)); write(@"</div></td> </tr> "); } write(@" </tbody> </table> </div> <div id=""explanation""> <p> You're seeing this error because you use <code>Gate.Helpers.ShowExceptions</code>. </p> </div> </body> </html> "); } catch { return; } }
public IAsyncResult BeginProcessRequest(HttpContextBase httpContext, AsyncCallback callback, object state) { var taskCompletionSource = new TaskCompletionSource<Action>(state); if (callback != null) taskCompletionSource.Task.ContinueWith(task => callback(task), TaskContinuationOptions.ExecuteSynchronously); var call = new CallParameters(); var httpRequest = httpContext.Request; var serverVariables = new ServerVariables(httpRequest.ServerVariables); var pathBase = httpRequest.ApplicationPath; if (pathBase == "/" || pathBase == null) pathBase = ""; var path = httpRequest.Path; if (path.StartsWith(pathBase)) path = path.Substring(pathBase.Length); call.Headers = httpRequest.Headers.AllKeys .ToDictionary(x => x, x => httpRequest.Headers.GetValues(x), StringComparer.OrdinalIgnoreCase); call.Body = httpRequest.InputStream; call.Environment = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase) { {OwinConstants.Version, "1.0"}, {OwinConstants.RequestMethod, httpRequest.HttpMethod}, {OwinConstants.RequestScheme, httpRequest.Url.Scheme}, {OwinConstants.RequestPathBase, pathBase}, {OwinConstants.RequestPath, path}, {OwinConstants.RequestQueryString, serverVariables.QueryString}, {OwinConstants.RequestProtocol, serverVariables.ProtocolVersion}, {"aspnet.HttpContextBase", httpContext}, {OwinConstants.CallCompleted, taskCompletionSource.Task}, }; foreach (var kv in serverVariables.AddToEnvironment()) { call.Environment["server." + kv.Key] = kv.Value; } try { _app.Invoke(call) .Then(result => { try { httpContext.Response.BufferOutput = false; httpContext.Response.StatusCode = result.Status; // TODO: Reason phrase foreach (var header in result.Headers) { foreach (var value in header.Value) { httpContext.Response.AddHeader(header.Key, value); } } if (result.Body != null) { result.Body(httpContext.Response.OutputStream) .Then(() => { taskCompletionSource.TrySetResult(() => { }); }) .Catch(errorInfo => { taskCompletionSource.TrySetException(errorInfo.Exception); return errorInfo.Handled(); }); } } catch (Exception ex) { taskCompletionSource.TrySetException(ex); } }) .Catch(errorInfo => { taskCompletionSource.TrySetException(errorInfo.Exception); return errorInfo.Handled(); }); } catch (Exception ex) { taskCompletionSource.TrySetException(ex); } return taskCompletionSource.Task; }
private Task<ResultParameters> Serve(CallParameters call) { var fileInfo = new FileInfo(path); var size = fileInfo.Length; int status; var headers = Headers.New() .SetHeader("Last-Modified", fileInfo.LastWriteTimeUtc.ToHttpDateString()) .SetHeader("Content-Type", Mime.MimeType(fileInfo.Extension, "text/plain")); if (!RangeHeader.IsValid(call.Headers)) { status = OK; range = new Tuple<long, long>(0, size - 1); } else { var ranges = RangeHeader.Parse(call.Headers, size); if (ranges == null) { // Unsatisfiable. Return error and file size. return Fail( RequestedRangeNotSatisfiable, "Byte range unsatisfiable", Headers.New().SetHeader("Content-Range", "bytes */" + size)) .Invoke(call); } if (ranges.Count() > 1) { // TODO: Support multiple byte ranges. status = OK; range = new Tuple<long, long>(0, size - 1); } else { // Partial content range = ranges.First(); status = PartialContent; headers.SetHeader("Content-Range", "bytes " + range.Item1 + "-" + range.Item2 + "/" + size); size = range.Item2 - range.Item1 + 1; } } headers.SetHeader("Content-Length", size.ToString()); return TaskHelpers.FromResult(new ResultParameters { Status = status, Headers = headers, Body = FileBody.Create(path, range), Properties = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase) }); }
private void Serve(CallParameters call, Action<ResultParameters, Exception> callback) { var fileInfo = new FileInfo(path); var size = fileInfo.Length; int status; var headers = Headers.New() .SetHeader("Last-Modified", fileInfo.LastWriteTimeUtc.ToHttpDateString()) .SetHeader("Content-Type", Mime.MimeType(fileInfo.Extension, "text/plain")); if (!RangeHeader.IsValid(call.Headers)) { status = OK; range = new Tuple<long, long>(0, size - 1); } else { var ranges = RangeHeader.Parse(call.Headers, size); if (ranges == null) { // Unsatisfiable. Return error and file size. Fail( RequestedRangeNotSatisfiable, "Byte range unsatisfiable", Headers.New().SetHeader("Content-Range", "bytes */" + size)) .Invoke(call, callback); } if (ranges.Count() > 1) { // TODO: Support multiple byte ranges. status = OK; range = new Tuple<long, long>(0, size - 1); } else { // Partial content range = ranges.First(); status = PartialContent; headers.SetHeader("Content-Range", "bytes " + range.Item1 + "-" + range.Item2 + "/" + size); size = range.Item2 - range.Item1 + 1; } } headers.SetHeader("Content-Length", size.ToString()); try { callback(new ResultParameters { Status = status, Headers = headers, Body = FileBody.Create(path, range) }, null); } catch (Exception ex) { callback(default(ResultParameters), ex); } }