public static AppDelegate App() { return call => { var request = new Request(call); var response = new Response { Buffer = true, 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>"); response.End(); return response.GetResultAsync(); }; }
public void NormalPassThrough_Success() { AppFunc middleware = new PassiveValidator( env => { env[OwinConstants.ResponseStatusCode] = 200; return TaskHelpers.Completed(); }).Invoke; Request request = Request.Create(); request.CancellationToken = new CancellationTokenSource().Token; request.Body = Stream.Null; request.Method = "GET"; request.Path = "/foo"; request.PathBase = string.Empty; request.Protocol = "HTTP/1.1"; request.QueryString = "foo=bar"; request.Scheme = "http"; request.Version = "1.0"; request.HostWithPort = "hostname:8080"; request.Environment[OwinConstants.ResponseBody] = new MemoryStream(); middleware(request.Environment).Wait(); Response response = new Response(request.Environment); Assert.That(response.StatusCode, Is.EqualTo(200), ReadBody(response.OutputStream)); Assert.That(response.Headers.GetHeader("X-OwinValidatorWarning"), Is.Null); }
public void Async_Exception_in_response_body_stream_should_be_formatted_as_it_passes_through() { var stack = Build(b => b .UseShowExceptions() .UseFunc<AppDelegate>(_=>appCall => { Response appResult = new Response(200); appResult.Headers.SetHeader("Content-Type", "text/html"); appResult.StartAsync().Then( resp1 => { resp1.Write("<p>so far so good</p>"); resp1.Error(new ApplicationException("failed sending body async")); }); return appResult.ResultTask; })); ResultParameters result = stack(new Request().Call).Result; Assert.That(result.Status, Is.EqualTo(200)); Assert.That(result.Headers.GetHeader("Content-Type"), Is.EqualTo("text/html")); String bodyText = ReadBody(result.Body); Assert.That(bodyText, Is.StringContaining("<p>so far so good</p>")); Assert.That(bodyText, Is.StringContaining("failed sending body async")); }
public Task Invoke(IDictionary<string, object> env) { var request = new Request(env); var response = new Response(env) { 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"; } return TimerLoop(350, () => response.Write("<title>Hutchtastic</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>")); }
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 void Async_Exception_in_response_body_stream_should_be_formatted_as_it_passes_through() { var stack = Build(b => b .UseShowExceptions() .UseFunc<AppFunc>(_ => appEnv => { Response appResponse = new Response(appEnv); appResponse.StatusCode = 200; appResponse.Headers.SetHeader("Content-Type", "text/html"); byte[] bodyBytes = Encoding.ASCII.GetBytes("<p>so far so good</p>"); appResponse.OutputStream.Write(bodyBytes, 0, bodyBytes.Length); return TaskHelpers.FromError(new ApplicationException("failed sending body async")); })); Request request = Request.Create(); Response response = new Response(request.Environment); MemoryStream buffer = new MemoryStream(); response.OutputStream = buffer; stack(request.Environment).Wait(); Assert.That(response.StatusCode, Is.EqualTo(200)); Assert.That(response.Headers.GetHeader("Content-Type"), Is.EqualTo("text/html")); String bodyText = ReadBody(buffer); Assert.That(bodyText, Is.StringContaining("<p>so far so good</p>")); Assert.That(bodyText, Is.StringContaining("failed sending body async")); }
private static AppFunc Fail(int status, string body, string headerName = null, string headerValue = null) { return env => { Request request = new Request(env); Response response = new Response(env); response.StatusCode = status; response.Headers .SetHeader("Content-Type", "text/plain") .SetHeader("Content-Length", body.Length.ToString(CultureInfo.InvariantCulture)) .SetHeader("X-Cascade", "pass"); if (headerName != null && headerValue != null) { response.Headers.SetHeader(headerName, headerValue); } if ("HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase)) { return TaskHelpers.Completed(); } return response.WriteAsync(body); }; }
public static AppFunc Middleware(AppFunc app) { return env => { Action<Exception, Action<byte[], int, int>> showErrorMessage = (ex, write) => ErrorPage(env, ex, text => { var data = Encoding.ASCII.GetBytes(text); write(data, 0, data.Length); }); Func<Exception, Task> showErrorPage = ex => { var response = new Response(env) { Status = "500 Internal Server Error", ContentType = "text/html" }; showErrorMessage(ex, response.Write); return TaskHelpers.Completed(); }; // Don't try to modify the headers after the first write has occurred. TriggerStream triggerStream = new TriggerStream(env.Get<Stream>(OwinConstants.ResponseBody)); env[OwinConstants.ResponseBody] = triggerStream; bool bodyHasStarted = false; triggerStream.OnFirstWrite = () => { bodyHasStarted = true; }; try { return app(env) .Catch(errorInfo => { if (!bodyHasStarted) { showErrorPage(errorInfo.Exception).Wait(); } else { showErrorMessage(errorInfo.Exception, triggerStream.Write); } return errorInfo.Handled(); }); } catch (Exception exception) { if (!bodyHasStarted) { return showErrorPage(exception); } else { showErrorMessage(exception, triggerStream.Write); return TaskHelpers.Completed(); } } }; }
AppFunc SetStatusApp(int statusCode) { return env => { var resp = new Response(env) {StatusCode = statusCode}; return TaskHelpers.Completed(); }; }
public void ItCanDeleteCookies() { var response = new Response(); response.SetCookie("foo", "bar"); response.SetCookie("foo2", "bar2"); response.DeleteCookie("foo"); Assert.That(response.GetHeaders("Set-Cookie"), Is.EquivalentTo(new[] { "foo2=bar2; path=/", "foo=; expires=Thu, 01-Jan-1970 00:00:00 GMT" })); }
public static AppDelegate Middleware(AppDelegate app) { return call => { Action<Exception, Action<byte[]>> showErrorMessage = (ex, write) => ErrorPage(call, ex, text => { var data = Encoding.ASCII.GetBytes(text); write(data); }); Func<Exception, Task<ResultParameters>> showErrorPage = ex => { var response = new Response() { Status = "500 Internal Server Error", ContentType = "text/html" }; showErrorMessage(ex, data => response.Write(data)); return response.EndAsync(); }; try { return app(call) .Then(result => { if (result.Body != null) { var nestedBody = result.Body; result.Body = stream => { try { return nestedBody(stream).Catch( errorInfo => { showErrorMessage(errorInfo.Exception, data => stream.Write(data, 0, data.Length)); return errorInfo.Handled(); }); } catch (Exception ex) { showErrorMessage(ex, data => stream.Write(data, 0, data.Length)); return TaskHelpers.Completed(); } }; } return result; }) .Catch(errorInfo => { return errorInfo.Handled(showErrorPage(errorInfo.Exception).Result); }); } catch (Exception exception) { return showErrorPage(exception); } }; }
public static Task Call(IDictionary<string, object> env) { Response response = new Response(env); response.StatusCode = 404; response.ReasonPhrase = "Not Found"; response.Headers.SetHeader("Content-Type", new[] {"text/html"}); response.OutputStream.Write(body, 0, body.Length); return response.EndAsync(); }
public void Cascade_with_app_calls_through() { var cascade = Build(b => b.UseCascade(SetStatusApp(200))); Request request = Request.Create(); Response response = new Response(request.Environment); cascade(request.Environment).Wait(); Assert.That(response.StatusCode, Is.EqualTo(200)); }
public void Cascade_with_no_apps_should_return_404() { var cascade = Build(b => b.UseCascade(new AppFunc[0])); Request request = Request.Create(); Response response = new Response(request.Environment); cascade(request.Environment).Wait(); Assert.That(response.StatusCode, Is.EqualTo(404)); }
public Task Invoke(IDictionary<string, object> env) { Request request = new Request(env); Response response = new Response(env); Stream orriginalStream = response.OutputStream; TriggerStream triggerStream = new TriggerStream(orriginalStream); response.OutputStream = triggerStream; MemoryStream buffer = null; triggerStream.OnFirstWrite = () => { if (IsStatusWithNoNoEntityBody(response.StatusCode) || response.Headers.ContainsKey("Content-Length") || response.Headers.ContainsKey("Transfer-Encoding")) { return; } // Buffer buffer = new MemoryStream(); triggerStream.InnerStream = buffer; }; env[OwinConstants.ResponseBody] = triggerStream; return nextApp(env).Then(() => { if (buffer != null) { if (buffer.Length == 0) { response.Headers.SetHeader("Content-Length", "0"); } else { response.Headers.SetHeader("Content-Length", buffer.Length.ToString(CultureInfo.InvariantCulture)); // Suppress the body for HEAD requests. if (!"HEAD".Equals(request.Method, StringComparison.OrdinalIgnoreCase)) { buffer.Seek(0, SeekOrigin.Begin); return buffer.CopyToAsync(orriginalStream); } } } else if (!IsStatusWithNoNoEntityBody(response.StatusCode) && !response.Headers.ContainsKey("Content-Length") && !response.Headers.ContainsKey("Transfer-Encoding")) { // There were no Writes. response.Headers.SetHeader("Content-Length", "0"); } return TaskHelpers.Completed(); }); }
public static AppDelegate AsyncApp() { return 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(()=> { Delay }); return response.GetResultAsync(); ThreadPool.QueueUserWorkItem(_ => { try { 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.Start(() => TimerLoop(350, response.Error, () => response.Write("<title>Hutchtastic</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>"), response.End)); } catch (Exception ex) { callback(default(ResultParameters), ex); } }); }; }
public static AppDelegate Middleware(AppDelegate app) { return (call, callback) => { Action<Exception, Action<ArraySegment<byte>>> showErrorMessage = (ex, write) => ErrorPage(call, ex, text => { var data = Encoding.ASCII.GetBytes(text); write(new ArraySegment<byte>(data)); }); Action<Exception> showErrorPage = ex => { var response = new Response(callback) { Status = "500 Internal Server Error", ContentType = "text/html" }; response.Start(() => { showErrorMessage(ex, data => response.Write(data)); response.End(); }); }; try { app(call, (result, error) => { if (error != null) { showErrorPage(error); } else { var body = result.Body; result.Body = (write, end, cancel) => { showErrorPage = ex => { if (ex != null) { showErrorMessage(ex, data => write(data, null)); } end(null); }; body.Invoke(write, showErrorPage, cancel); }; callback(result, null); } }); } catch (Exception exception) { showErrorPage(exception); } }; }
public static AppDelegate Middleware(AppDelegate app) { return (env, result, fault) => { Action<Exception, Action<ArraySegment<byte>>> showErrorMessage = (ex, write) => ErrorPage(env, ex, text => { var data = Encoding.ASCII.GetBytes(text); write(new ArraySegment<byte>(data)); }); Action<Exception> showErrorPage = ex => { var response = new Response(result) { Status = "500 Internal Server Error", ContentType = "text/html" }; response.Start(() => { showErrorMessage(ex, data => response.Write(data)); response.End(); }); }; try { app( env, (status, headers, body) => result( status, headers, (write, flush, end, token) => { showErrorPage = ex => { if (ex != null) { showErrorMessage(ex, data => write(data)); } end(null); }; body( write, flush, showErrorPage, token); }), ex => showErrorPage(ex)); } catch (Exception exception) { showErrorPage(exception); } }; }
private IDictionary<string, string[]> Call(Action<IAppBuilder> pipe) { var builder = new AppBuilder(); pipe(builder); var app = (AppFunc)builder.Build(typeof(AppFunc)); var env = Request.Create().Environment; var resp = new Response(env); resp.OutputStream = new MemoryStream(); app(env).Wait(); return resp.Headers; }
private string Call(Action<IAppBuilder> pipe, Request request) { var builder = new AppBuilder(); pipe(builder); var app = (AppFunc)builder.Build(typeof(AppFunc)); var env = request.Environment; var resp = new Response(env); MemoryStream buffer = new MemoryStream(); resp.OutputStream = buffer; app(env).Wait(); return Encoding.UTF8.GetString(buffer.GetBuffer(), 0, (int)buffer.Length); }
public void Finish_will_call_result_delegate_with_current_status_and_headers() { var response = new Response() { Status = "200 Blah", ContentType = "text/blah", }; ResultParameters result = response.EndAsync().Result; Assert.That(result.Status, Is.EqualTo(200)); Assert.That(result.Headers.GetHeader("Content-Type"), Is.EqualTo("text/blah")); }
public void FileServer_returns_error_for_unsatisfiable_byte_range() { Request request = Request.Create(); request.Method = "GET"; request.Path = "/test.txt"; request.Headers.SetHeader("Range", "bytes=1234-5678"); Response response = new Response(request.Environment); response.OutputStream = new MemoryStream(); fileServer.Invoke(request.Environment).Wait(); Assert.That(response.StatusCode, Is.EqualTo(416)); // Requested Range Not Satisfiable Assert.That(response.Headers.GetHeader("Content-Range"), Is.EqualTo("bytes */193")); }
public void Finish_will_call_result_delegate_with_current_status_and_headers() { var env = CreateEmptyEnvironment(); var response = new Response(env) { Status = "200 Blah", ContentType = "text/blah", }; Assert.That(env.Get<int>("owin.ResponseStatusCode"), Is.EqualTo(200)); Assert.That(env.Get<string>("owin.ResponseReasonPhrase"), Is.EqualTo("Blah")); Assert.That(env.Get<IDictionary<string, string[]>>("owin.ResponseHeaders").GetHeader("Content-Type"), Is.EqualTo("text/blah")); }
public void Finish_will_call_result_delegate_with_current_status_and_headers() { var response = new Response(Result) { Status = "200 Blah", ContentType = "text/blah", }; Assert.That(_status, Is.Null); response.End(); Assert.That(_status, Is.EqualTo("200 Blah")); Assert.That(_headers.GetHeader("Content-Type"), Is.EqualTo("text/blah")); }
private int Call(Action<IAppBuilder> pipe, string path) { var builder = new AppBuilder(); pipe(builder); var app = builder.Build<AppFunc>(); Request request = Request.Create(); request.Path = path; request.Method = "GET"; Response response = new Response(request.Environment); response.OutputStream = new MemoryStream(); app(request.Environment).Wait(); return response.StatusCode; }
public override IResponse Call(IRequest request) { Response response = new Response(); switch (request.Uri) { case "/badResponse": response.SetBody(5); // add unkown object type into body break; default: response.Write("You requested {0} {1}", request.Method, request.Uri); break; } return response; }
public void FileServer_returns_correct_byte_range_in_body() { Request request = Request.Create(); request.Method = "GET"; request.Path = "/test.txt"; request.Headers.SetHeader("Range", "bytes=22-33"); Response response = new Response(request.Environment); response.OutputStream = new MemoryStream(); fileServer.Invoke(request.Environment).Wait(); Assert.That(response.StatusCode, Is.EqualTo(206)); // Partial content Assert.That(response.Headers.GetHeader("Content-Length"), Is.EqualTo("12")); Assert.That(response.Headers.GetHeader("Content-Range"), Is.EqualTo("bytes 22-33/193")); Assert.That(ReadBody(response.OutputStream), Is.EqualTo("-*- test -*-")); }
public void Cascade_will_pass_along_to_first_non_404_app() { AppFunc app1 = SetStatusApp(404); AppFunc app2 = SetStatusApp(200); AppFunc app3 = env => TaskHelpers.FromError<object>( new ApplicationException("This should not have been invoked")); var cascade = Build(b => b.UseCascade(app1, app2, app3)); Request request = Request.Create(); Response response = new Response(request.Environment); cascade(request.Environment).Wait(); Assert.That(response.StatusCode, Is.EqualTo(200)); }
public static void WriteResponse(HttpResponse aspNetResponse, IResponse owinResponse) { Response response = new Response(owinResponse); aspNetResponse.Status = response.Status; aspNetResponse.Write(response.BodyText); // if you try to access Headers directly, you'll get: // PlatformNotSupportedException: This operation requires IIS integrated pipeline mode. // // you *can* call AddHeader() however // foreach (KeyValuePair<string,IEnumerable<string>> header in response.Headers) foreach (string value in header.Value) aspNetResponse.AddHeader(header.Key, value); }
public static Task Call(IDictionary<string, object> env) { Response response = new Response(env) { StatusCode = 404, ReasonPhrase = "Not Found", ContentType = "text/html", ContentLength = body.Length, }; if ("HEAD".Equals(new Request(env).Method, StringComparison.OrdinalIgnoreCase)) { return TaskHelpers.Completed(); } return response.WriteAsync(body); }