public async Task ClientReceivesInternalServerErrorWhenTheApplicationFails() { using (StartVerifiableLog()) { var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext))) { Transport = pair.Transport, Application = pair.Application, }; using (var feature = new TestWebSocketConnectionFeature()) { var connectionContext = new HttpConnectionContext(string.Empty, null, null); var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connectionContext, LoggerFactory); // Give the server socket to the transport and run it var transport = ws.ProcessSocketAsync(await feature.AcceptAsync()); // Run the client socket var client = feature.Client.ExecuteAndCaptureFramesAsync(); // Fail in the app connection.Transport.Output.Complete(new InvalidOperationException("Catastrophic failure.")); var clientSummary = await client.OrTimeout(); Assert.Equal(WebSocketCloseStatus.InternalServerError, clientSummary.CloseResult.CloseStatus); // Close from the client await feature.Client.CloseAsync(WebSocketCloseStatus.NormalClosure, "", CancellationToken.None); await transport.OrTimeout(); } } }
public Task StartAsync(Uri url, TransferFormat transferFormat) { var options = ClientPipeOptions.DefaultOptions; var pair = DuplexPipe.CreateConnectionPair(options, options); _transport = pair.Transport; _application = pair.Application; _tries++; Assert.True(QueryHelpers.ParseQuery(url.Query).TryGetValue("id", out var id)); if (_prevConnectionId == null) { _prevConnectionId = id; } else { Assert.True(_prevConnectionId != id); _prevConnectionId = id; } if (_tries < availableTransports) { return(Task.FromException(new Exception())); } else { return(Task.CompletedTask); } }
public TestInput(IKestrelTrace log = null, ITimeoutControl timeoutControl = null) { _memoryPool = PinnedBlockMemoryPoolFactory.Create(); var options = new PipeOptions(pool: _memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); Transport = pair.Transport; Application = pair.Application; var connectionFeatures = new FeatureCollection(); connectionFeatures.Set(Mock.Of <IConnectionLifetimeFeature>()); Http1ConnectionContext = TestContextFactory.CreateHttpConnectionContext( serviceContext: new TestServiceContext { Log = log ?? Mock.Of <IKestrelTrace>() }, connectionContext: Mock.Of <ConnectionContext>(), transport: Transport, timeoutControl: timeoutControl ?? Mock.Of <ITimeoutControl>(), memoryPool: _memoryPool, connectionFeatures: connectionFeatures); Http1Connection = new Http1Connection(Http1ConnectionContext); Http1Connection.HttpResponseControl = Mock.Of <IHttpResponseControl>(); Http1Connection.Reset(); }
public void Setup() { _memoryPool = SlabMemoryPoolFactory.Create(); var options = new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); var serviceContext = TestContextFactory.CreateServiceContext( serverOptions: new KestrelServerOptions(), httpParser: new HttpParser <Http1ParsingHandler>(), dateHeaderValueManager: new DateHeaderValueManager(), log: new MockTrace()); var connectionContext = TestContextFactory.CreateHttpConnectionContext( serviceContext: serviceContext, connectionContext: null, transport: pair.Transport, memoryPool: _memoryPool, connectionFeatures: new FeatureCollection(), timeoutControl: new TimeoutControl(timeoutHandler: null)); var http1Connection = new Http1Connection(connectionContext); http1Connection.Reset(); Http1Connection = http1Connection; Pipe = new Pipe(new PipeOptions(_memoryPool)); }
public void GlobalSetup() { _hubLifetimeManager = new DefaultHubLifetimeManager <Hub>(NullLogger <DefaultHubLifetimeManager <Hub> > .Instance); IHubProtocol protocol; if (Protocol == "json") { protocol = new JsonHubProtocol(); } else { protocol = new MessagePackHubProtocol(); } var options = new PipeOptions(); for (var i = 0; i < Connections; ++i) { var pair = DuplexPipe.CreateConnectionPair(options, options); var connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), pair.Application, pair.Transport); var hubConnection = new HubConnectionContext(connection, Timeout.InfiniteTimeSpan, NullLoggerFactory.Instance); hubConnection.Protocol = protocol; _hubLifetimeManager.OnConnectedAsync(hubConnection).GetAwaiter().GetResult(); _ = ConsumeAsync(connection.Application); } _hubContext = new HubContext <Hub>(_hubLifetimeManager); }
public QuicStreamContext(QuicStream stream, QuicConnectionContext connection, QuicTransportContext context) { _stream = stream; _connection = connection; _context = context; _log = context.Log; MemoryPool = connection.MemoryPool; ConnectionClosed = _streamClosedTokenSource.Token; var maxReadBufferSize = context.Options.MaxReadBufferSize ?? 0; var maxWriteBufferSize = context.Options.MaxWriteBufferSize ?? 0; // TODO should we allow these PipeScheduler to be configurable here? var inputOptions = new PipeOptions(MemoryPool, PipeScheduler.ThreadPool, PipeScheduler.Inline, maxReadBufferSize, maxReadBufferSize / 2, useSynchronizationContext: false); var outputOptions = new PipeOptions(MemoryPool, PipeScheduler.Inline, PipeScheduler.ThreadPool, maxWriteBufferSize, maxWriteBufferSize / 2, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions); Features.Set <IStreamDirectionFeature>(this); Features.Set <IProtocolErrorCodeFeature>(this); Features.Set <IStreamIdFeature>(this); // TODO populate the ITlsConnectionFeature (requires client certs). Features.Set <ITlsConnectionFeature>(new FakeTlsConnectionFeature()); CanRead = stream.CanRead; CanWrite = stream.CanWrite; Transport = _originalTransport = pair.Transport; Application = pair.Application; }
private TestHttp1Connection MakeHttp1Connection() { var options = new PipeOptions(_memoryPool, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); _pair = pair; var serviceContext = TestContextFactory.CreateServiceContext( serverOptions: new KestrelServerOptions(), httpParser: new HttpParser <Http1ParsingHandler>(), dateHeaderValueManager: new DateHeaderValueManager(), log: new MockTrace()); var connectionContext = TestContextFactory.CreateHttpConnectionContext( serviceContext: serviceContext, connectionContext: null, transport: pair.Transport, timeoutControl: new TimeoutControl(timeoutHandler: null), memoryPool: _memoryPool, connectionFeatures: new FeatureCollection()); var http1Connection = new TestHttp1Connection(connectionContext); http1Connection.Reset(); http1Connection.InitializeBodyControl(MessageBody.ZeroContentLengthKeepAlive); serviceContext.DateHeaderValueManager.OnHeartbeat(DateTimeOffset.UtcNow); return(http1Connection); }
public async Task SSEWritesVeryLargeMessages() { using (StartVerifiableLog()) { var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, new PipeOptions(readerScheduler: PipeScheduler.Inline)); var connection = new DefaultConnectionContext("foo", pair.Transport, pair.Application); var context = new DefaultHttpContext(); var ms = new MemoryStream(); context.Response.Body = ms; var sse = new ServerSentEventsServerTransport(connection.Application.Input, connectionId: string.Empty, LoggerFactory); var task = sse.ProcessRequestAsync(context, context.RequestAborted); string hText = new string('H', 60000); string wText = new string('W', 60000); await connection.Transport.Output.WriteAsync(Encoding.ASCII.GetBytes(hText + wText)); connection.Transport.Output.Complete(); await task.OrTimeout(); Assert.Equal(":\r\ndata: " + hText + wText + "\r\n\r\n", Encoding.ASCII.GetString(ms.ToArray())); } }
public TestClient(bool synchronousCallbacks = false, IHubProtocol protocol = null, IInvocationBinder invocationBinder = null, bool addClaimId = false) { var options = new PipeOptions(readerScheduler: synchronousCallbacks ? PipeScheduler.Inline : null); var pair = DuplexPipe.CreateConnectionPair(options, options); Connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), pair.Transport, pair.Application); var claimValue = Interlocked.Increment(ref _id).ToString(); var claims = new List <Claim> { new Claim(ClaimTypes.Name, claimValue) }; if (addClaimId) { claims.Add(new Claim(ClaimTypes.NameIdentifier, claimValue)); } Connection.User = new ClaimsPrincipal(new ClaimsIdentity(claims)); Connection.Metadata["ConnectedTask"] = new TaskCompletionSource <bool>(); protocol = protocol ?? new JsonHubProtocol(); _protocolReaderWriter = new HubProtocolReaderWriter(protocol, new PassThroughEncoder()); _invocationBinder = invocationBinder ?? new DefaultInvocationBinder(); _cts = new CancellationTokenSource(); using (var memoryStream = new MemoryStream()) { NegotiationProtocol.WriteMessage(new NegotiationMessage(protocol.Name), memoryStream); Connection.Application.Output.WriteAsync(memoryStream.ToArray()); } }
public virtual void GlobalSetup() { _memoryPool = PinnedBlockMemoryPoolFactory.Create(); _httpFrame = new Http2Frame(); var options = new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); _connectionPair = DuplexPipe.CreateConnectionPair(options, options); _httpRequestHeaders = new HttpRequestHeaders(); _httpRequestHeaders.HeaderMethod = new StringValues("GET"); _httpRequestHeaders.HeaderPath = new StringValues("/"); _httpRequestHeaders.HeaderScheme = new StringValues("http"); _httpRequestHeaders.HeaderAuthority = new StringValues("localhost:80"); _headersBuffer = new byte[1024 * 16]; _hpackEncoder = new DynamicHPackEncoder(); var serviceContext = TestContextFactory.CreateServiceContext( serverOptions: new KestrelServerOptions(), dateHeaderValueManager: new DateHeaderValueManager(), systemClock: new MockSystemClock(), log: new MockTrace()); serviceContext.DateHeaderValueManager.OnHeartbeat(default);
public LibuvConnection(UvStreamHandle socket, ILibuvTrace log, LibuvThread thread, IPEndPoint remoteEndPoint, IPEndPoint localEndPoint, PipeOptions inputOptions = null, PipeOptions outputOptions = null, long?maxReadBufferSize = null, long?maxWriteBufferSize = null) { _socket = socket; LocalEndPoint = localEndPoint; RemoteEndPoint = remoteEndPoint; ConnectionClosed = _connectionClosedTokenSource.Token; Log = log; Thread = thread; maxReadBufferSize ??= 0; maxWriteBufferSize ??= 0; inputOptions ??= new PipeOptions(MemoryPool, PipeScheduler.ThreadPool, Thread, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false); outputOptions ??= new PipeOptions(MemoryPool, Thread, PipeScheduler.ThreadPool, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions); // Set the transport and connection id Transport = pair.Transport; Application = pair.Application; }
public Http1ConnectionTests() { _pipelineFactory = KestrelMemoryPool.Create(); var options = new PipeOptions(_pipelineFactory, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); _transport = pair.Transport; _application = pair.Application; var connectionFeatures = new FeatureCollection(); connectionFeatures.Set(Mock.Of <IConnectionLifetimeFeature>()); _serviceContext = new TestServiceContext(); _timeoutControl = new Mock <ITimeoutControl>(); _http1ConnectionContext = new HttpConnectionContext { ServiceContext = _serviceContext, ConnectionContext = Mock.Of <ConnectionContext>(), ConnectionFeatures = connectionFeatures, MemoryPool = _pipelineFactory, TimeoutControl = _timeoutControl.Object, Transport = pair.Transport }; _http1Connection = new TestHttp1Connection(_http1ConnectionContext); _http1Connection.Reset(); }
private TestHttp1Connection MakeHttp1Connection() { var options = new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); _pair = pair; var serviceContext = new ServiceContext { DateHeaderValueManager = new DateHeaderValueManager(), ServerOptions = new KestrelServerOptions(), Log = new MockTrace(), HttpParser = new HttpParser <Http1ParsingHandler>() }; var http1Connection = new TestHttp1Connection(new HttpConnectionContext { ServiceContext = serviceContext, ConnectionFeatures = new FeatureCollection(), MemoryPool = _memoryPool, TimeoutControl = new TimeoutControl(timeoutHandler: null), Transport = pair.Transport }); http1Connection.Reset(); http1Connection.InitializeBodyControl(MessageBody.ZeroContentLengthKeepAlive); serviceContext.DateHeaderValueManager.OnHeartbeat(DateTimeOffset.UtcNow); return(http1Connection); }
public void Setup() { _memoryPool = KestrelMemoryPool.Create(); var options = new PipeOptions(_memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); var serviceContext = new ServiceContext { DateHeaderValueManager = new DateHeaderValueManager(), ServerOptions = new KestrelServerOptions(), Log = new MockTrace(), HttpParser = new HttpParser <Http1ParsingHandler>() }; var http1Connection = new Http1Connection(new HttpConnectionContext { ServiceContext = serviceContext, ConnectionFeatures = new FeatureCollection(), MemoryPool = _memoryPool, Transport = pair.Transport, TimeoutControl = new TimeoutControl(timeoutHandler: null) }); http1Connection.Reset(); Http1Connection = http1Connection; Pipe = new Pipe(new PipeOptions(_memoryPool)); }
public async Task ShortMaskedViaManagedWebsocketWorks() { var options = new PipeOptions(useSynchronizationContext: false); var duplexPipe = DuplexPipe.CreateConnectionPair(options, options); var webSocket = WebSocket.CreateFromStream(new DuplexPipeStream(duplexPipe.Transport.Input, duplexPipe.Transport.Output), false, null, TimeSpan.FromSeconds(30)); var data = new ReadOnlyMemory <byte>(Encoding.UTF8.GetBytes("This is a test payload.")); await webSocket.SendAsync(data, WebSocketMessageType.Binary, true, default); var result = await duplexPipe.Application.Input.ReadAsync(); var maskingKey = ReadMaskingKey(result.Buffer, 2); duplexPipe.Application.Input.AdvanceTo(result.Buffer.GetPosition(6)); result = await duplexPipe.Application.Input.ReadAsync(); var reader = new WebSocketPayloadReader(new WebSocketHeader(true, WebSocketOpcode.Binary, true, 23, maskingKey)); SequencePosition pos = default; reader.TryParseMessage(result.Buffer, ref pos, ref pos, out var message); var resultString = Encoding.UTF8.GetString(result.Buffer.ToArray()); Assert.Equal("This is a test payload.", resultString); }
public void Setup() { var memoryPool = PinnedBlockMemoryPoolFactory.Create(); var options = new PipeOptions(memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); var serviceContext = TestContextFactory.CreateServiceContext( serverOptions: new KestrelServerOptions(), httpParser: new HttpParser <Http1ParsingHandler>(), dateHeaderValueManager: _dateHeaderValueManager, log: new MockTrace()); var connectionContext = TestContextFactory.CreateHttpConnectionContext( serviceContext: serviceContext, connectionContext: null, transport: pair.Transport, memoryPool: memoryPool, connectionFeatures: new FeatureCollection()); var http1Connection = new Http1Connection(connectionContext); http1Connection.Reset(); serviceContext.DateHeaderValueManager.OnHeartbeat(DateTimeOffset.UtcNow); _responseHeadersDirect = (HttpResponseHeaders)http1Connection.ResponseHeaders; var context = new DefaultHttpContext(http1Connection); _response = context.Response; switch (Type) { case BenchmarkTypes.ContentLengthNumeric: SetContentLengthNumeric(1); GetContentLengthNumeric(1); break; case BenchmarkTypes.ContentLengthString: SetContentLengthString(1); GetContentLengthString(1); break; case BenchmarkTypes.Plaintext: SetPlaintext(1); GetPlaintext(1); break; case BenchmarkTypes.Common: SetCommon(1); GetCommon(1); break; case BenchmarkTypes.Unknown: SetUnknown(1); GetUnknown(1); break; } }
public Http3HttpProtocolFeatureCollectionTests() { var streamContext = TestContextFactory.CreateHttp3StreamContext(transport: DuplexPipe.CreateConnectionPair(new PipeOptions(), new PipeOptions()).Application); var http3Stream = new TestHttp3Stream(); http3Stream.Initialize(streamContext); _http3Collection = http3Stream; }
public async Task SSETransportStopsSendAndReceiveLoopsWhenTransportStopped() { var eventStreamCts = new CancellationTokenSource(); var mockHttpHandler = new Mock <HttpMessageHandler>(); mockHttpHandler.Protected() .Setup <Task <HttpResponseMessage> >("SendAsync", ItExpr.IsAny <HttpRequestMessage>(), ItExpr.IsAny <CancellationToken>()) .Returns <HttpRequestMessage, CancellationToken>((request, cancellationToken) => { var mockStream = new Mock <Stream>(); mockStream .Setup(s => s.CopyToAsync(It.IsAny <Stream>(), It.IsAny <int>(), It.IsAny <CancellationToken>())) .Returns <Stream, int, CancellationToken>(async(stream, bufferSize, t) => { await Task.Yield(); var buffer = Encoding.ASCII.GetBytes("data: 3:abc\r\n\r\n"); while (!eventStreamCts.IsCancellationRequested) { await stream.WriteAsync(buffer, 0, buffer.Length).OrTimeout(); } }); mockStream.Setup(s => s.CanRead).Returns(true); return(Task.FromResult(new HttpResponseMessage { Content = new StreamContent(mockStream.Object) })); }); Task transportActiveTask; using (var httpClient = new HttpClient(mockHttpHandler.Object)) { var sseTransport = new ServerSentEventsTransport(httpClient); try { var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); await sseTransport.StartAsync( new Uri("http://fakeuri.org"), pair.Application, TransferFormat.Text, connection : Mock.Of <IConnection>()).OrTimeout(); transportActiveTask = sseTransport.Running; Assert.False(transportActiveTask.IsCompleted); var message = await pair.Transport.Input.ReadSingleAsync().OrTimeout(); Assert.StartsWith("3:abc", Encoding.ASCII.GetString(message)); } finally { await sseTransport.StopAsync().OrTimeout(); } await transportActiveTask.OrTimeout(); eventStreamCts.Cancel(); } }
internal SocketConnection(Socket socket, MemoryPool <byte> memoryPool, PipeScheduler scheduler, ISocketsTrace trace, long?maxReadBufferSize = null, long?maxWriteBufferSize = null, bool deferSends = true, bool deferReceives = true, SocketContinuationScheduler socketScheduler = SocketContinuationScheduler.ThreadPool, InputScheduler inputScheduler = InputScheduler.ThreadPool, bool dontAllocateMemoryForIdleConnections = true, OutputScheduler outputScheduler = OutputScheduler.IOQueue) { Debug.Assert(socket != null); Debug.Assert(memoryPool != null); Debug.Assert(trace != null); _socket = socket; MemoryPool = memoryPool; _trace = trace; _waitForReceiveReady = dontAllocateMemoryForIdleConnections; LocalEndPoint = _socket.LocalEndPoint; RemoteEndPoint = _socket.RemoteEndPoint; ConnectionClosed = _connectionClosedTokenSource.Token; // On *nix platforms, Sockets already dispatches to the ThreadPool. // Yes, the IOQueues are still used for the PipeSchedulers. This is intentional. // https://github.com/aspnet/KestrelHttpServer/issues/2573 var awaiterScheduler = IsWindows ? scheduler : PipeScheduler.Inline; _receiver = new SocketReceiver(_socket, awaiterScheduler, runContinuationsAsynchronously: socketScheduler == SocketContinuationScheduler.ThreadPool, preferSynchronousCompletion: !deferReceives); _sender = new SocketSender(_socket, awaiterScheduler, runContinuationsAsynchronously: socketScheduler == SocketContinuationScheduler.ThreadPool, preferSynchronousCompletion: !deferSends); maxReadBufferSize ??= 0; maxWriteBufferSize ??= 0; PipeScheduler pipeScheduler = outputScheduler switch { OutputScheduler.Inline => PipeScheduler.Inline, OutputScheduler.IOQueue => scheduler, OutputScheduler.IOThread => _socket.IOThreadScheduler, OutputScheduler.ThreadPool => PipeScheduler.ThreadPool, _ => throw new IndexOutOfRangeException() }; var appScheduler = inputScheduler == InputScheduler.Inline ? PipeScheduler.Inline : PipeScheduler.ThreadPool; var inputOptions = new PipeOptions(MemoryPool, appScheduler, scheduler, maxReadBufferSize.Value, maxReadBufferSize.Value / 2, useSynchronizationContext: false); var outputOptions = new PipeOptions(MemoryPool, pipeScheduler, appScheduler, maxWriteBufferSize.Value, maxWriteBufferSize.Value / 2, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions); // Set the transport and connection id Transport = pair.Transport; Application = pair.Application; }
public async Task TransportCommunicatesErrorToApplicationWhenClientDisconnectsAbnormally() { using (StartVerifiableLog()) { var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext1")) { Transport = pair.Transport, Application = pair.Application, }; using (var feature = new TestWebSocketConnectionFeature()) { async Task CompleteApplicationAfterTransportCompletes() { try { // Wait until the transport completes so that we can end the application var result = await connection.Transport.Input.ReadAsync(); connection.Transport.Input.AdvanceTo(result.Buffer.End); } catch (Exception ex) { Assert.IsType <WebSocketError>(ex); } finally { // Complete the application so that the connection unwinds without aborting connection.Transport.Output.Complete(); } } var connectionContext = new HttpConnectionContext(string.Empty, connectionToken: null, LoggerFactory.CreateLogger("HttpConnectionContext2")); var ws = new WebSocketsServerTransport(new WebSocketOptions(), connection.Application, connectionContext, LoggerFactory); // Give the server socket to the transport and run it var transport = ws.ProcessSocketAsync(await feature.AcceptAsync()); // Run the client socket var client = feature.Client.ExecuteAndCaptureFramesAsync(); // When the close frame is received, we complete the application so the send // loop unwinds _ = CompleteApplicationAfterTransportCompletes(); // Terminate the client to server channel with an exception feature.Client.SendAbort(); // Wait for the transport await transport.OrTimeout(); await client.OrTimeout(); } } }
public async Task ReadMessagesAsynchronouslyWorks() { var options = new PipeOptions(useSynchronizationContext: false, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline); var pair = DuplexPipe.CreateConnectionPair(options, options); await using var connection = new DefaultConnectionContext(Guid.NewGuid().ToString(), pair.Transport, pair.Application); var data = Encoding.UTF8.GetBytes("Hello World"); var protocol = new TestProtocol(); async Task WritingTask() { var writer = connection.Application.Output; for (var i = 0; i < 3; i++) { protocol.WriteMessage(data, writer); await writer.FlushAsync().ConfigureAwait(false); } await writer.CompleteAsync().ConfigureAwait(false); } async Task ReadingTask() { var reader = connection.CreatePipeReader(protocol); while (true) { var result = await reader.ReadAsync().ConfigureAwait(false); var buffer = result.Buffer; if (buffer.Length < 3 * data.Length) { reader.AdvanceTo(buffer.Start, buffer.End); continue; } Assert.Equal(Enumerable.Repeat(data, 3).SelectMany(a => a).ToArray(), buffer.ToArray()); reader.AdvanceTo(buffer.End); result = await reader.ReadAsync().ConfigureAwait(false); Assert.True(result.IsCompleted); break; } await reader.CompleteAsync(); } var readingTask = ReadingTask(); var writingTask = WritingTask(); await writingTask; await readingTask; }
protected override Task <ConnectionContext> CreateConnection(string target = null) { var pipeOptions = new PipeOptions(); var duplex = DuplexPipe.CreateConnectionPair(pipeOptions, pipeOptions); return(Task.FromResult <ConnectionContext>(new DefaultConnectionContext() { Application = duplex.Application, Transport = duplex.Transport })); }
public ValueTask <IConnection> StartAsync() { _serialPort.Open(); var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); Transport = pair.Transport; _application = pair.Application; return(new ValueTask <IConnection>(this)); }
public Http3RequestStream(Http3TestBase testBase, Http3Connection connection) { _testBase = testBase; _connection = connection; var inputPipeOptions = GetInputPipeOptions(_testBase._serviceContext, _testBase._memoryPool, PipeScheduler.ThreadPool); var outputPipeOptions = GetOutputPipeOptions(_testBase._serviceContext, _testBase._memoryPool, PipeScheduler.ThreadPool); _pair = DuplexPipe.CreateConnectionPair(inputPipeOptions, outputPipeOptions); StreamContext = new TestStreamContext(canRead: true, canWrite: true, _pair, this); }
public TestConnection() { Features = new FeatureCollection(); Items = new ConcurrentDictionary <object, object>(); var pipeOptions = new PipeOptions(); var pair = DuplexPipe.CreateConnectionPair(pipeOptions, pipeOptions); Transport = pair.Transport; Application = pair.Application; }
public InMemoryConnection() { var inputOptions = new PipeOptions(useSynchronizationContext: false); var outputOptions = new PipeOptions(useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(inputOptions, outputOptions); // Set the transport and connection id Transport = pair.Transport; Application = pair.Application; }
public async Task StartAsync() { await _socket.ConnectAsync(_endPoint); var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); _transport = pair.Transport; _application = pair.Application; _ = ExecuteAsync(); }
public async Task StartAsync(Uri url, TransferFormat transferFormat) { if (url == null) { throw new ArgumentNullException(nameof(url)); } if (transferFormat != TransferFormat.Binary && transferFormat != TransferFormat.Text) { throw new ArgumentException($"The '{transferFormat}' transfer format is not supported by this transport.", nameof(transferFormat)); } _webSocketMessageType = transferFormat == TransferFormat.Binary ? WebSocketMessageType.Binary : WebSocketMessageType.Text; var resolvedUrl = ResolveWebSocketsUrl(url); // We don't need to capture to a local because we never change this delegate. if (_accessTokenProvider != null) { var accessToken = await _accessTokenProvider(); if (!string.IsNullOrEmpty(accessToken)) { _webSocket.Options.SetRequestHeader("Authorization", $"Bearer {accessToken}"); } } Log.StartTransport(_logger, transferFormat, resolvedUrl); try { await _webSocket.ConnectAsync(resolvedUrl, CancellationToken.None); } catch { _webSocket.Dispose(); throw; } Log.StartedTransport(_logger); // Create the pipe pair (Application's writer is connected to Transport's reader, and vice versa) var options = ClientPipeOptions.DefaultOptions; var pair = DuplexPipe.CreateConnectionPair(options, options); _transport = pair.Transport; _application = pair.Application; // TODO: Handle TCP connection errors // https://github.com/SignalR/SignalR/blob/1fba14fa3437e24c204dfaf8a18db3fce8acad3c/src/Microsoft.AspNet.SignalR.Core/Owin/WebSockets/WebSocketHandler.cs#L248-L251 Running = ProcessSocketAsync(_webSocket); }
public async Task SubProtocolSelectorIsUsedToSelectSubProtocol() { const string ExpectedSubProtocol = "expected"; var providedSubProtocols = new[] { "provided1", "provided2" }; using (StartVerifiableLog()) { var pair = DuplexPipe.CreateConnectionPair(PipeOptions.Default, PipeOptions.Default); var connection = new HttpConnectionContext("foo", connectionToken: null, LoggerFactory.CreateLogger(nameof(HttpConnectionContext))) { Transport = pair.Transport, Application = pair.Application, }; using (var feature = new TestWebSocketConnectionFeature()) { var options = new WebSocketOptions { // We want to verify behavior without timeout affecting it CloseTimeout = TimeSpan.FromSeconds(20), SubProtocolSelector = protocols => { Assert.Equal(providedSubProtocols, protocols.ToArray()); return(ExpectedSubProtocol); }, }; var connectionContext = new HttpConnectionContext(string.Empty, null, null); var ws = new WebSocketsServerTransport(options, connection.Application, connectionContext, LoggerFactory); // Create an HttpContext var context = new DefaultHttpContext(); context.Request.Headers.Add(HeaderNames.WebSocketSubProtocols, providedSubProtocols.ToArray()); context.Features.Set <IHttpWebSocketFeature>(feature); var transport = ws.ProcessRequestAsync(context, CancellationToken.None); await feature.Accepted.OrThrowIfOtherFails(transport); // Assert the feature got the right subprotocol Assert.Equal(ExpectedSubProtocol, feature.SubProtocol); // Run the client socket var client = feature.Client.ExecuteAndCaptureFramesAsync(); await feature.Client.CloseOutputAsync(WebSocketCloseStatus.NormalClosure, null, CancellationToken.None).OrTimeout(); // close the client to server channel connection.Transport.Output.Complete(); _ = await client.OrTimeout(); await transport.OrTimeout(); } } }
public void Setup() { var memoryPool = KestrelMemoryPool.Create(); var options = new PipeOptions(memoryPool, readerScheduler: PipeScheduler.Inline, writerScheduler: PipeScheduler.Inline, useSynchronizationContext: false); var pair = DuplexPipe.CreateConnectionPair(options, options); var serviceContext = new ServiceContext { DateHeaderValueManager = _dateHeaderValueManager, ServerOptions = new KestrelServerOptions(), Log = new MockTrace(), HttpParser = new HttpParser <Http1ParsingHandler>() }; var http1Connection = new Http1Connection(new HttpConnectionContext { ServiceContext = serviceContext, ConnectionFeatures = new FeatureCollection(), MemoryPool = memoryPool, Transport = pair.Transport }); http1Connection.Reset(); serviceContext.DateHeaderValueManager.OnHeartbeat(DateTimeOffset.UtcNow); _responseHeadersDirect = (HttpResponseHeaders)http1Connection.ResponseHeaders; var context = new DefaultHttpContext(http1Connection); _response = new DefaultHttpResponse(context); switch (Type) { case BenchmarkTypes.ContentLengthNumeric: ContentLengthNumeric(1); break; case BenchmarkTypes.ContentLengthString: ContentLengthString(1); break; case BenchmarkTypes.Plaintext: Plaintext(1); break; case BenchmarkTypes.Common: Common(1); break; case BenchmarkTypes.Unknown: Unknown(1); break; } }