public ResponseStream(bool disableWrites, Action flush) { _disableWrites = disableWrites; _flush = flush; _currentStream = new MemoryStream(); _cancellationTokenSource = new SafeCancellationTokenSource(); _cancellationToken = _cancellationTokenSource.Token; }
public ClientStream(INetworkObserver networkObserver, SafeCancellationTokenSource callCancelledTokenSource) { _cancelToken = _cancelTokenSource.Token; _callCancelledTokenSource = callCancelledTokenSource; networkObserver.OnCancel = () => { _cancelTokenSource.Cancel(useNewThread: false); _callCancelledTokenSource.Cancel(); }; networkObserver.OnClose = OnClose; networkObserver.OnWrite = OnWrite; }
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; }
protected virtual Task InitializePersistentState() { _hostShutdownToken = _context.Environment.GetShutdownToken(); _requestLifeTime = new HttpRequestLifeTime(this, WriteQueue, Trace, ConnectionId); // Create the TCS that completes when the task returned by PersistentConnection.OnConnected does. _connectTcs = new TaskCompletionSource<object>(); // Create a token that represents the end of this connection's life _connectionEndTokenSource = new SafeCancellationTokenSource(); _connectionEndToken = _connectionEndTokenSource.Token; // Handle the shutdown token's callback so we can end our token if it trips _hostRegistration = _hostShutdownToken.SafeRegister(state => { ((SafeCancellationTokenSource)state).Cancel(); }, _connectionEndTokenSource); // When the connection ends release the request _connectionEndRegistration = CancellationToken.SafeRegister(state => { ((HttpRequestLifeTime)state).Complete(); }, _requestLifeTime); return InitializeMessageId(); }
private Task<IClientResponse> ProcessRequest(string httpMethod, string url, Action<IClientRequest> prepareRequest, IDictionary<string, string> postData, bool disableWrites = false) { 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.RequestProtocol] = "HTTP/1.1"; env[OwinConstants.CallCancelled] = clientTokenSource.Token; env[OwinConstants.RequestMethod] = httpMethod; 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; headers.SetHeader("X-Server", "MemoryHost"); headers.SetHeader("X-Server-Name", InstanceName); if (httpMethod == "POST") { headers.SetHeader("Content-Type", "application/x-www-form-urlencoded"); } // Run the client function to initialize the request prepareRequest(new Request(env, clientTokenSource.Cancel)); var networkObservable = new NetworkObservable(disableWrites); var clientStream = new ClientStream(networkObservable); var serverStream = new ServerStream(networkObservable); var response = new Response(clientStream); // Trigger the tcs on flush. This mimicks the client side networkObservable.OnFlush = () => tcs.TrySetResult(response); // Cancel the network observable on cancellation of the token clientTokenSource.Token.Register(networkObservable.Cancel); env[OwinConstants.ResponseBody] = serverStream; 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); } // Close the server stream when the request has ended serverStream.Close(); clientTokenSource.Dispose(); }); return tcs.Task; }
protected virtual void InitializePersistentState() { _hostShutdownToken = _context.HostShutdownToken(); Completed = new TaskCompletionSource<object>(); // Create a token that represents the end of this connection's life _connectionEndTokenSource = new SafeCancellationTokenSource(); _connectionEndToken = _connectionEndTokenSource.Token; // Handle the shutdown token's callback so we can end our token if it trips _hostRegistration = _hostShutdownToken.SafeRegister(state => { state.Cancel(); }, _connectionEndTokenSource); }
/// <summary> /// Starts the <see cref="Connection"/>. /// </summary> /// <param name="transport">The transport to use.</param> /// <returns>A task that represents when the connection has started.</returns> public Task Start(IClientTransport transport) { _disconnectCts = new SafeCancellationTokenSource(); if (!ChangeState(ConnectionState.Disconnected, ConnectionState.Connecting)) { return TaskAsyncHelper.Empty; } _transport = transport; return Negotiate(transport); }
public Task<IClientResponse> ProcessRequest(string url, Action<IClientRequest> prepareRequest, Dictionary<string, string> postData, bool disableWrites) { if (url == null) { throw new ArgumentNullException("url"); } if (prepareRequest == null) { throw new ArgumentNullException("prepareRequest"); } var uri = new Uri(url); PersistentConnection connection; if (!_shutDownToken.IsCancellationRequested && TryGetConnection(uri.LocalPath, out connection)) { var tcs = new TaskCompletionSource<IClientResponse>(); var clientTokenSource = new SafeCancellationTokenSource(); var request = new Request(uri, clientTokenSource.Cancel, postData, User); prepareRequest(request); Response response = null; response = new Response(clientTokenSource.Token, () => tcs.TrySetResult(response)) { DisableWrites = disableWrites }; var hostContext = new HostContext(request, response); hostContext.Items[HostConstants.ShutdownToken] = _shutDownTokenSource.Token; connection.Initialize(DependencyResolver, hostContext); connection.ProcessRequestAsync(hostContext).ContinueWith(task => { if (task.IsFaulted) { tcs.TrySetException(task.Exception); } else if (task.IsCanceled) { tcs.TrySetCanceled(); } else { tcs.TrySetResult(response); } response.Close(); clientTokenSource.Dispose(); }); return tcs.Task; } return TaskAsyncHelper.FromError<IClientResponse>(new InvalidOperationException("Not a valid end point")); }
protected virtual void InitializePersistentState() { _hostShutdownToken = _context.HostShutdownToken(); _requestLifeTime = new HttpRequestLifeTime(WriteQueue, Trace, ConnectionId); // Create a token that represents the end of this connection's life _connectionEndTokenSource = new SafeCancellationTokenSource(); _connectionEndToken = _connectionEndTokenSource.Token; // Handle the shutdown token's callback so we can end our token if it trips _hostRegistration = _hostShutdownToken.SafeRegister(state => { ((SafeCancellationTokenSource)state).Cancel(); }, _connectionEndTokenSource); // When the connection ends release the request _connectionEndRegistration = CancellationToken.SafeRegister(state => { ((HttpRequestLifeTime)state).Complete(); }, _requestLifeTime); }
public ResponseStream() { _currentStream = new MemoryStream(); _cancellationTokenSource = new SafeCancellationTokenSource(); _cancellationToken = _cancellationTokenSource.Token; }