public async Task OnConnectionAsync(ConnectionContext connectionContext) { // We need the transport feature so that we can cancel the output reader that the transport is using // This is a bit of a hack but it preserves the existing semantics var memoryPoolFeature = connectionContext.Features.Get <IMemoryPoolFeature>(); var httpConnectionId = Interlocked.Increment(ref _lastHttpConnectionId); var httpConnectionContext = new HttpConnectionContext { ConnectionId = connectionContext.ConnectionId, ConnectionContext = connectionContext, HttpConnectionId = httpConnectionId, Protocols = _protocols, ServiceContext = _serviceContext, ConnectionFeatures = connectionContext.Features, MemoryPool = memoryPoolFeature.MemoryPool, ConnectionAdapters = _connectionAdapters, Transport = connectionContext.Transport }; var connectionFeature = connectionContext.Features.Get <IHttpConnectionFeature>(); var lifetimeFeature = connectionContext.Features.Get <IConnectionLifetimeFeature>(); if (connectionFeature != null) { if (connectionFeature.LocalIpAddress != null) { httpConnectionContext.LocalEndPoint = new IPEndPoint(connectionFeature.LocalIpAddress, connectionFeature.LocalPort); } if (connectionFeature.RemoteIpAddress != null) { httpConnectionContext.RemoteEndPoint = new IPEndPoint(connectionFeature.RemoteIpAddress, connectionFeature.RemotePort); } } var connection = new HttpConnection(httpConnectionContext); _serviceContext.ConnectionManager.AddConnection(httpConnectionId, connection); try { var processingTask = connection.ProcessRequestsAsync(_application); connectionContext.Transport.Input.OnWriterCompleted( (_, state) => ((HttpConnection)state).OnInputOrOutputCompleted(), connection); connectionContext.Transport.Output.OnReaderCompleted( (_, state) => ((HttpConnection)state).OnInputOrOutputCompleted(), connection); await CancellationTokenAsTask(lifetimeFeature.ConnectionClosed); connection.OnConnectionClosed(); await processingTask; } finally { _serviceContext.ConnectionManager.RemoveConnection(httpConnectionId); } }
public Task OnConnectionAsync(ConnectionContext connectionContext) { // We need the transport feature so that we can cancel the output reader that the transport is using // This is a bit of a hack but it preserves the existing semantics var transportFeature = connectionContext.Features.Get <IConnectionTransportFeature>(); var httpConnectionId = Interlocked.Increment(ref _lastHttpConnectionId); var httpConnectionContext = new HttpConnectionContext { ConnectionId = connectionContext.ConnectionId, HttpConnectionId = httpConnectionId, Protocols = _protocols, ServiceContext = _serviceContext, ConnectionFeatures = connectionContext.Features, MemoryPool = connectionContext.MemoryPool, ConnectionAdapters = _connectionAdapters, Transport = connectionContext.Transport, Application = transportFeature.Application }; var connectionFeature = connectionContext.Features.Get <IHttpConnectionFeature>(); if (connectionFeature != null) { if (connectionFeature.LocalIpAddress != null) { httpConnectionContext.LocalEndPoint = new IPEndPoint(connectionFeature.LocalIpAddress, connectionFeature.LocalPort); } if (connectionFeature.RemoteIpAddress != null) { httpConnectionContext.RemoteEndPoint = new IPEndPoint(connectionFeature.RemoteIpAddress, connectionFeature.RemotePort); } } var connection = new HttpConnection(httpConnectionContext); var processingTask = connection.StartRequestProcessing(_application); var inputTcs = new TaskCompletionSource <object>(); var outputTcs = new TaskCompletionSource <object>(); // The reason we don't fire events directly from these callbacks is because it seems // like the transport callbacks root the state object (even after it fires) connectionContext.Transport.Input.OnWriterCompleted(_completeTcs, inputTcs); connectionContext.Transport.Output.OnReaderCompleted(_completeTcs, outputTcs); inputTcs.Task.ContinueWith((task, state) => { ((HttpConnection)state).Abort(task.Exception?.InnerException); }, connection, TaskContinuationOptions.ExecuteSynchronously); outputTcs.Task.ContinueWith((task, state) => { ((HttpConnection)state).OnConnectionClosed(task.Exception?.InnerException); }, connection, TaskContinuationOptions.ExecuteSynchronously); return(processingTask); }
public HttpConnection(HttpConnectionContext context) { _context = context; }
public HttpConnection(HttpConnectionContext context) { _context = context; _systemClock = _context.ServiceContext.SystemClock; }