public async Task BidirectionalStreaming(string scheme) { var hostBuilder = new HostBuilder() .ConfigureWebHost(webHostBuilder => { ConfigureKestrel(webHostBuilder, scheme); webHostBuilder.ConfigureServices(AddTestLogging) .Configure(app => app.Run(async context => { var reader = context.Request.BodyReader; // Read Hello World and echo it back to the client, twice for (var i = 0; i < 2; i++) { var readResult = await reader.ReadAsync().DefaultTimeout(); while (!readResult.IsCompleted && readResult.Buffer.Length < "Hello World".Length) { reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); readResult = await reader.ReadAsync().DefaultTimeout(); } var sequence = readResult.Buffer.Slice(0, "Hello World".Length); Assert.True(sequence.IsSingleSegment); await context.Response.BodyWriter.WriteAsync(sequence.First).DefaultTimeout(); reader.AdvanceTo(sequence.End); } var finalResult = await reader.ReadAsync().DefaultTimeout(); Assert.True(finalResult.IsCompleted && finalResult.Buffer.Length == 0); })); }); using var host = await hostBuilder.StartAsync().DefaultTimeout(); var url = host.MakeUrl(scheme); using var client = CreateClient(); client.DefaultRequestHeaders.ExpectContinue = true; var streamingContent = new StreamingContent(); var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); var responseTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // The server won't send headers until it gets the first message await streamingContent.SendAsync("Hello World").DefaultTimeout(); var response = await responseTask; Assert.Equal(HttpVersion.Version20, response.Version); var stream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); await ReadStreamHelloWorld(stream); await streamingContent.SendAsync("Hello World").DefaultTimeout(); streamingContent.Complete(); await ReadStreamHelloWorld(stream); Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout()); await host.StopAsync().DefaultTimeout(); }
public async Task ReverseEcho(string scheme) { var clientEcho = new TaskCompletionSource <string>(TaskCreationOptions.RunContinuationsAsynchronously); var hostBuilder = new HostBuilder() .ConfigureWebHost(webHostBuilder => { ConfigureKestrel(webHostBuilder, scheme); webHostBuilder.ConfigureServices(AddTestLogging) .Configure(app => app.Run(async context => { // Prime it? // var readTask = context.Request.BodyReader.ReadAsync(); context.Response.ContentType = "text/plain"; await context.Response.WriteAsync("Hello World"); await context.Response.CompleteAsync().DefaultTimeout(); try { // var readResult = await readTask; // context.Request.BodyReader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); using var streamReader = new StreamReader(context.Request.Body); var read = await streamReader.ReadToEndAsync().DefaultTimeout(); clientEcho.SetResult(read); } catch (Exception ex) { clientEcho.SetException(ex); } })); }); using var host = await hostBuilder.StartAsync().DefaultTimeout(); var url = host.MakeUrl(scheme); using var client = CreateClient(); // client.DefaultRequestHeaders.ExpectContinue = true; var streamingContent = new StreamingContent(); var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); using var response = await client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); Assert.Equal(HttpVersion.Version20, response.Version); // Read Hello World and echo it back to the server. /* https://github.com/dotnet/corefx/issues/39404 * var read = await response.Content.ReadAsStringAsync().DefaultTimeout(); * Assert.Equal("Hello World", read); */ var stream = await response.Content.ReadAsStreamAsync().DefaultTimeout(); await ReadStreamHelloWorld(stream).DefaultTimeout(); Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout()); stream.Dispose(); // https://github.com/dotnet/corefx/issues/39404 can be worked around by commenting out this Dispose await streamingContent.SendAsync("Hello World").DefaultTimeout(); streamingContent.Complete(); Assert.Equal("Hello World", await clientEcho.Task.DefaultTimeout()); await host.StopAsync().DefaultTimeout(); }
public async Task BidirectionalStreamingMoreClientData(string scheme) { var lastPacket = new TaskCompletionSource <string>(TaskCreationOptions.RunContinuationsAsynchronously); var hostBuilder = new HostBuilder() .ConfigureWebHost(webHostBuilder => { ConfigureKestrel(webHostBuilder, scheme); webHostBuilder.ConfigureServices(AddTestLogging) .Configure(app => app.Run(async context => { var reader = context.Request.BodyReader; var readResult = await reader.ReadAsync().DefaultTimeout(); while (!readResult.IsCompleted && readResult.Buffer.Length < "Hello World".Length) { reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); readResult = await reader.ReadAsync().DefaultTimeout(); } var sequence = readResult.Buffer.Slice(0, "Hello World".Length); Assert.True(sequence.IsSingleSegment); await context.Response.BodyWriter.WriteAsync(sequence.First).DefaultTimeout(); reader.AdvanceTo(sequence.End); await context.Response.CompleteAsync().DefaultTimeout(); try { // The client sends one more packet after the server completes readResult = await reader.ReadAsync().DefaultTimeout(); while (!readResult.IsCompleted && readResult.Buffer.Length < "Hello World".Length) { reader.AdvanceTo(readResult.Buffer.Start, readResult.Buffer.End); readResult = await reader.ReadAsync().DefaultTimeout(); } Assert.True(readResult.Buffer.IsSingleSegment); var result = Encoding.UTF8.GetString(readResult.Buffer.FirstSpan); reader.AdvanceTo(readResult.Buffer.End); var finalResult = await reader.ReadAsync().DefaultTimeout(); Assert.True(finalResult.IsCompleted && finalResult.Buffer.Length == 0); lastPacket.SetResult(result); } catch (Exception ex) { lastPacket.SetException(ex); } })); }); using var host = await hostBuilder.StartAsync().DefaultTimeout(); var url = host.MakeUrl(scheme); using var client = CreateClient(); client.DefaultRequestHeaders.ExpectContinue = true; var streamingContent = new StreamingContent(); var request = CreateRequestMessage(HttpMethod.Post, url, streamingContent); var responseTask = client.SendAsync(request, HttpCompletionOption.ResponseHeadersRead).DefaultTimeout(); // The server doesn't respond until we send the first set of data await streamingContent.SendAsync("Hello World").DefaultTimeout(); var response = await responseTask; Assert.Equal(HttpVersion.Version20, response.Version); var stream = await response.Content.ReadAsStreamAsync(); await ReadStreamHelloWorld(stream); Assert.Equal(0, await stream.ReadAsync(new byte[10], 0, 10).DefaultTimeout()); stream.Dispose(); // https://github.com/dotnet/corefx/issues/39404 can be worked around by commenting out this Dispose // Send one more message after the server has finished. await streamingContent.SendAsync("Hello World").DefaultTimeout(); streamingContent.Complete(); var lastData = await lastPacket.Task.DefaultTimeout(); Assert.Equal("Hello World", lastData); await host.StopAsync().DefaultTimeout(); }