public Task<IClientResponse> ProcessRequest(string url, Action<IClientRequest> prepareRequest, IDictionary<string, string> postData, bool disableWrites) { if (url == null) { throw new ArgumentNullException("url"); } if (prepareRequest == null) { throw new ArgumentNullException("prepareRequest"); } if (_appFunc == null) { throw new InvalidOperationException(); } if (_shutDownToken.IsCancellationRequested) { return TaskAsyncHelper.FromError<IClientResponse>(new InvalidOperationException("Service unavailable")); } var tcs = new TaskCompletionSource<IClientResponse>(); var clientTokenSource = new SafeCancellationTokenSource(); var env = new Dictionary<string, object>(); // Server specific setup env[OwinConstants.Version] = "1.0"; // Request specific setup var uri = new Uri(url); env[OwinConstants.CallCancelled] = clientTokenSource.Token; string method = postData == null ? "GET" : "POST"; env[OwinConstants.RequestMethod] = method; env[OwinConstants.RequestPathBase] = String.Empty; env[OwinConstants.RequestPath] = uri.LocalPath; env[OwinConstants.RequestQueryString] = uri.Query.Length > 0 ? uri.Query.Substring(1) : String.Empty; env[OwinConstants.RequestScheme] = uri.Scheme; env[OwinConstants.RequestBody] = GetRequestBody(postData); var headers = new Dictionary<string, string[]>(); env[OwinConstants.RequestHeaders] = headers; if (method == "POST") { headers.SetHeader("Content-Type", "application/x-www-form-urlencoded"); } // Run the client function to initialize the request prepareRequest(new Request(env, clientTokenSource.Cancel)); Response response = null; response = new Response(disableWrites, () => tcs.TrySetResult(response)); env[OwinConstants.ResponseBody] = response.GetResponseStream(); env[OwinConstants.ResponseHeaders] = new Dictionary<string, string[]>(); _appFunc(env).ContinueWith(task => { object statusCode; if (env.TryGetValue(OwinConstants.ResponseStatusCode, out statusCode) && (int)statusCode == 403) { tcs.TrySetException(new InvalidOperationException("Forbidden")); } else if (task.IsFaulted) { tcs.TrySetException(task.Exception.InnerExceptions); } else if (task.IsCanceled) { tcs.TrySetCanceled(); } else { tcs.TrySetResult(response); } response.Close(); clientTokenSource.Dispose(); }); return tcs.Task; }