static AppDelegate App(AppDelegate arg) { return call => { ResultParameters result = new ResultParameters() { Status = 200, Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) { { "Content-Type", new[] { "text/plain" } } }, Properties = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase), Body = stream => { var bytes = Encoding.Default.GetBytes("This is a custom page"); stream.Write(bytes, 0, bytes.Length); TaskCompletionSource<object> bodyTcs = new TaskCompletionSource<object>(); bodyTcs.TrySetResult(null); return bodyTcs.Task; } }; TaskCompletionSource<ResultParameters> requestTcs = new TaskCompletionSource<ResultParameters>(); requestTcs.TrySetResult(result); return requestTcs.Task; }; }
static ResultParameters WrapBodyDelegate(ResultParameters result) { if (result.Body != null) { var nestedBody = result.Body; result.Body = stream => { TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(); ExecutionContext.SuppressFlow(); ThreadPool.QueueUserWorkItem( _ => nestedBody(stream) .Then(() => { bool ignored = tcs.TrySetResult(null); }) .Catch(errorInfo => { bool ignored = tcs.TrySetException(errorInfo.Exception); return errorInfo.Handled(); }), null); ExecutionContext.RestoreFlow(); return tcs.Task; }; } return result; }
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); }
private string GetStatus(ResultParameters result) { string status = result.Status.ToString(CultureInfo.InvariantCulture); object obj; if (result.Properties != null && result.Properties.TryGetValue(OwinConstants.ReasonPhrase, out obj)) { string reason = (string)obj; if (!string.IsNullOrWhiteSpace(reason)) { status += " " + reason; } } return status; }
public Response(ResultParameters result, CancellationToken completed = default(CancellationToken)) { this.defaultBodyDelegate = DefaultBodyDelegate; this.result.Status = result.Status; this.result.Body = result.Body ?? defaultBodyDelegate; this.result.Headers = result.Headers ?? new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase); this.result.Properties = result.Properties ?? new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); this.callCompletionSource = new TaskCompletionSource<ResultParameters>(); this.sendHeaderAsyncCompletionSource = new TaskCompletionSource<Response>(); this.bodyTransitionCompletionSource = new TaskCompletionSource<object>(); this.bodyCompletionSource = new TaskCompletionSource<object>(); this.completeToken = completed; this.Encoding = defaultEncoding; }
public Response(int statusCode, IDictionary<string, string[]> headers, IDictionary<string, object> properties) { _startCalled = StartCalled; _result = new ResultParameters { Status = statusCode, Headers = headers, Body = ResponseBodyAsync, Properties = properties }; _responseWrite = EarlyResponseWrite; _responseWriteAsync = EarlyResponseWriteAsync; _responseFlush = EarlyResponseFlush; _responseFlushAsync = EarlyResponseFlushAsync; Encoding = Encoding.UTF8; }
private string GetStatus(ResultParameters result) { throw new NotImplementedException(); }
AppDelegate ReturnText(string text) { return call => { ResultParameters result = new ResultParameters(); result.Status = 200; result.Properties = new Dictionary<string, object>(StringComparer.OrdinalIgnoreCase); result.Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) { {"Content-Type", new[] {"text/plain"}}, {"X-Server", new[] {"inproc"}} }; result.Body = stream => { byte[] body = Encoding.ASCII.GetBytes(text); stream.Write(body, 0, body.Length); return TaskHelpers.Completed(); }; return TaskHelpers.FromResult(result); }; }
AppDelegate EchoRequestBody() { return call => { ResultParameters result = new ResultParameters(); result.Status = 200; result.Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) { {"Content-Type", call.Headers["Content-Type"].ToArray()} }; MemoryStream buffer = new MemoryStream(); call.Body.CopyTo(buffer); buffer.Seek(0, SeekOrigin.Begin); result.Body = stream => { buffer.CopyTo(stream); return TaskHelpers.Completed(); }; return TaskHelpers.FromResult(result); }; }
public void Sync_Exception_in_response_body_stream_should_be_formatted_as_it_passes_through() { var stack = Build(b => b .UseShowExceptions() .UseFunc<AppDelegate>(_ => appCall => { ResultParameters rawResult = new ResultParameters(); rawResult.Body = stream => { byte[] bodyBytes = Encoding.ASCII.GetBytes("<p>so far so good</p>"); stream.Write(bodyBytes, 0, bodyBytes.Length); throw new ApplicationException("failed sending body sync"); }; rawResult.Status = 200; Response appResult = new Response(rawResult); appResult.Headers.SetHeader("Content-Type", "text/html"); appResult.Start(); 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 sync")); }
private void HandleResponse(IHttpResponseDelegate response, ResultParameters result) { if (result.Headers == null) { result.Headers = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase); } if (result.Body != null && !result.Headers.ContainsKey("Content-Length") && !result.Headers.ContainsKey("Transfer-Encoding")) { // disable keep-alive in this case result.Headers["Connection"] = new[] { "close" }; } response.OnResponse(new HttpResponseHead() { Status = GetStatus(result), Headers = result.Headers.ToDictionary(kv => kv.Key, kv => string.Join("\r\n", kv.Value.ToArray()), StringComparer.OrdinalIgnoreCase), }, null /* result.Body == null ? null : new DataProducer(result.Body) */); // TODO: How do we expose DataProducer as a Stream? }
void StartCalled(ResultParameters result, Exception ex) { if (ex != null) { _callCompletionSource.SetException(ex); } else { _callCompletionSource.SetResult(result); } }