Пример #1
0
        public async Task Http2GetAsync_TrailingHeaders_NoData_EmptyResponseObserved()
        {
            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    Task <HttpResponseMessage> sendTask = client.GetAsync(server.Address);

                    Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                    int streamId = await connection.ReadRequestHeaderAsync();

                    // Response header.
                    await connection.SendDefaultResponseHeadersAsync(streamId);

                    // No data.

                    // Response trailing headers
                    await connection.SendResponseHeadersAsync(streamId, isTrailingHeader : true, headers : TrailingHeaders);

                    HttpResponseMessage response = await sendTask;
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                    Assert.Equal <byte>(Array.Empty <byte>(), await response.Content.ReadAsByteArrayAsync());

                    var trailingHeaders = GetTrailingHeaders(response);
                    Assert.Contains("amazingtrailer", trailingHeaders.GetValues("MyCoolTrailerHeader"));
                    Assert.Contains("World", trailingHeaders.GetValues("Hello"));
                }
        }
Пример #2
0
        public async Task UseClientCertOnHttp2_OSSupportsIt_Success()
        {
            using X509Certificate2 clientCert = Test.Common.Configuration.Certificates.GetClientCertificate();
            await Http2LoopbackServer.CreateClientAndServerAsync(
                async address =>
                {
                    var handler = new WinHttpHandler();
                    handler.ServerCertificateValidationCallback = CustomServerCertificateValidationCallback;
                    handler.ClientCertificates.Add(clientCert);
                    handler.ClientCertificateOption = ClientCertificateOption.Manual;
                    using (var client = new HttpClient(handler))
                    using (HttpResponseMessage response = await client.SendAsync(new HttpRequestMessage(HttpMethod.Get, address) { Version = HttpVersion20.Value }))
                    {
                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        Assert.True(_validationCallbackHistory.WasCalled);
                        Assert.NotEmpty(_validationCallbackHistory.CertificateChain);
                        Assert.Equal(Test.Common.Configuration.Certificates.GetServerCertificate(), _validationCallbackHistory.CertificateChain[0]);
                    }
                },
                async s =>
                {
                    await using (Http2LoopbackConnection connection = await s.EstablishConnectionAsync().ConfigureAwait(false))
                    {
                        SslStream sslStream = connection.Stream as SslStream;
                        Assert.NotNull(sslStream);
                        Assert.True(sslStream.IsMutuallyAuthenticated);
                        Assert.Equal(clientCert, sslStream.RemoteCertificate);

                        int streamId = await connection.ReadRequestHeaderAsync();
                        await connection.SendDefaultResponseAsync(streamId);
                    }
                }, new Http2Options { ClientCertificateRequired = true });
        }
        public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success()
        {
            using Http2LoopbackServer firstServer  = Http2LoopbackServer.CreateServer();
            using Http3LoopbackServer secondServer = new Http3LoopbackServer();
            using HttpClient client = CreateHttpClient(CreateHttpClientHandler(HttpVersion.Version30));

            Task <HttpResponseMessage> firstResponseTask = client.GetAsync(firstServer.Address);

            using (Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync())
            {
                int streamId = await connection.ReadRequestHeaderAsync();

                await connection.SendDefaultResponseHeadersAsync(streamId);

                await connection.WriteFrameAsync(new AltSvcFrame("", $"h3={secondServer.Address.IdnHost}:{secondServer.Address.Port}", streamId));

                await connection.SendResponseDataAsync(streamId, Array.Empty <byte>(), true);
            }

            HttpResponseMessage firstResponse = await firstResponseTask;

            Assert.True(firstResponse.IsSuccessStatusCode);

            await AltSvc_Upgrade_Success(firstServer, secondServer, client);
        }
Пример #4
0
        public async Task HPack_HeaderEncoding(string headerName, string expectedValue, byte[] expectedEncoding)
        {
            await Http2LoopbackServer.CreateClientAndServerAsync(
                async uri =>
            {
                using HttpClient client = CreateHttpClient();

                using HttpRequestMessage request = new HttpRequestMessage();
                request.Method     = HttpMethod.Post;
                request.RequestUri = uri;
                request.Version    = HttpVersion.Version20;
                request.Content    = new StringContent("testing 123");
                request.Headers.Add(LiteralHeaderName, LiteralHeaderValue);

                (await client.SendAsync(request)).Dispose();
            },
                async server =>
            {
                Http2LoopbackConnection connection          = await server.EstablishConnectionAsync();
                (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync();

                HttpHeaderData header = requestData.Headers.Single(x => x.Name == headerName);
                Assert.Equal(expectedValue, header.Value);
                Assert.True(expectedEncoding.AsSpan().SequenceEqual(header.Raw));

                await connection.SendDefaultResponseAsync(streamId);
            });
        }
        public Task BadRttPingResponse_RequestShouldFail(int mode)
        {
            return(Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
            {
                using var handler = CreateHttpClientHandler();
                using HttpClient client = CreateHttpClient(handler);
                HttpRequestException exception = await Assert.ThrowsAsync <HttpRequestException>(() => client.GetAsync(uri));
                _output.WriteLine(exception.Message + exception.StatusCode);
            },
                                                                  async server =>
            {
                Http2LoopbackConnection connection = await server.EstablishConnectionAsync();
                (int streamId, _) = await connection.ReadAndParseRequestHeaderAsync();
                await connection.SendDefaultResponseHeadersAsync(streamId);
                PingFrame pingFrame = await connection.ReadPingAsync(); // expect an RTT PING

                if (mode == 0)
                {
                    // Invalid PING payload
                    await connection.SendPingAckAsync(-6666); // send an invalid PING response
                }
                else
                {
                    // Unexpected PING response
                    await connection.SendPingAckAsync(pingFrame.Data);     // send an valid PING response
                    await connection.SendPingAckAsync(pingFrame.Data - 1); // send a second unexpected PING response
                }

                await connection.SendResponseDataAsync(streamId, new byte[] { 1, 2, 3 }, true); // otherwise fine response
            },
                                                                  NoAutoPingResponseHttp2Options));
        }
Пример #6
0
        public async Task Http2GetAsync_TrailerHeaders_TrailingHeaderNoBody()
        {
            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    Task <HttpResponseMessage> sendTask = client.GetAsync(server.Address);

                    Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                    int streamId = await connection.ReadRequestHeaderAsync();

                    // Response header.
                    await connection.SendDefaultResponseHeadersAsync(streamId);

                    await connection.SendResponseHeadersAsync(streamId, endStream : true, isTrailingHeader : true, headers : TrailingHeaders);

                    HttpResponseMessage response = await sendTask;
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    var trailingHeaders = GetTrailingHeaders(response);
                    Assert.Equal(TrailingHeaders.Count, trailingHeaders.Count());
                    Assert.Contains("amazingtrailer", trailingHeaders.GetValues("MyCoolTrailerHeader"));
                    Assert.Contains("World", trailingHeaders.GetValues("Hello"));
                }
        }
Пример #7
0
 public async Task ConnectAsync_VersionSupported_Success()
 {
     await Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
     {
         using (var cws = new ClientWebSocket())
             using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
             {
                 cws.Options.HttpVersion       = HttpVersion.Version20;
                 cws.Options.HttpVersionPolicy = Http.HttpVersionPolicy.RequestVersionExact;
                 using var handler             = CreateSocketsHttpHandler(allowAllCertificates: true);
                 await cws.ConnectAsync(uri, new HttpMessageInvoker(handler), cts.Token);
             }
     },
                                                          async server =>
     {
         Http2LoopbackConnection connection = await server.EstablishConnectionAsync(new SettingsEntry {
             SettingId = SettingId.EnableConnect, Value = 1
         });
         (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
         await connection.SendResponseHeadersAsync(streamId, endStream: false, HttpStatusCode.OK);
     }, new Http2Options()
     {
         WebSocketEndpoint = true
     }
                                                          );
 }
Пример #8
0
 public async Task ConnectAsync_VersionNotSupported_Throws()
 {
     await Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
     {
         using (var clientSocket = new ClientWebSocket())
             using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
             {
                 clientSocket.Options.HttpVersion       = HttpVersion.Version20;
                 clientSocket.Options.HttpVersionPolicy = Http.HttpVersionPolicy.RequestVersionExact;
                 using var handler = CreateSocketsHttpHandler(allowAllCertificates: true);
                 Task t            = clientSocket.ConnectAsync(uri, new HttpMessageInvoker(handler), cts.Token);
                 var ex            = await Assert.ThrowsAnyAsync <WebSocketException>(() => t);
                 Assert.IsType <HttpRequestException>(ex.InnerException);
                 Assert.True(ex.InnerException.Data.Contains("SETTINGS_ENABLE_CONNECT_PROTOCOL"));
             }
     },
                                                          async server =>
     {
         Http2LoopbackConnection connection = await server.EstablishConnectionAsync(new SettingsEntry {
             SettingId = SettingId.EnableConnect, Value = 0
         });
     }, new Http2Options()
     {
         WebSocketEndpoint = true
     }
                                                          );
 }
Пример #9
0
        public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success()
        {
            using Http2LoopbackServer firstServer  = Http2LoopbackServer.CreateServer();
            using Http3LoopbackServer secondServer = new Http3LoopbackServer();
            using HttpClient client = CreateHttpClient();

            Task <HttpResponseMessage> firstResponseTask = client.GetAsync(firstServer.Address);
            Task serverTask = Task.Run(async() =>
            {
                using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync();

                int streamId = await connection.ReadRequestHeaderAsync();
                await connection.SendDefaultResponseHeadersAsync(streamId);
                await connection.WriteFrameAsync(new AltSvcFrame("", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId));
                await connection.SendResponseDataAsync(streamId, Array.Empty <byte>(), true);
            });

            await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000);

            HttpResponseMessage firstResponse = firstResponseTask.Result;

            Assert.True(firstResponse.IsSuccessStatusCode);

            await AltSvc_Upgrade_Success(firstServer, secondServer, client);
        }
Пример #10
0
        public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success()
        {
            // [ActiveIssue("https://github.com/dotnet/runtime/issues/54050")]
            if (UseQuicImplementationProvider == QuicImplementationProviders.Mock)
            {
                return;
            }

            using Http2LoopbackServer firstServer  = Http2LoopbackServer.CreateServer();
            using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer();
            using HttpClient client = CreateHttpClient(HttpVersion.Version20);

            Task <HttpResponseMessage> firstResponseTask = client.GetAsync(firstServer.Address);
            Task serverTask = Task.Run(async() =>
            {
                using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync();

                int streamId = await connection.ReadRequestHeaderAsync();
                await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0));
                await connection.SendDefaultResponseAsync(streamId);
            });

            await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000);

            HttpResponseMessage firstResponse = firstResponseTask.Result;

            Assert.True(firstResponse.IsSuccessStatusCode);

            await AltSvc_Upgrade_Success(firstServer, secondServer, client);
        }
Пример #11
0
        public async Task Http2GetAsync_NoTrailingHeaders_EmptyCollection()
        {
            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    Task <HttpResponseMessage> sendTask = client.GetAsync(server.Address);

                    Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                    int streamId = await connection.ReadRequestHeaderAsync();

                    // Response header.
                    await connection.SendDefaultResponseHeadersAsync(streamId);

                    // Response data.
                    await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes, endStream : true));

                    // Server doesn't send trailing header frame.
                    HttpResponseMessage response = await sendTask;
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    var trailingHeaders = GetTrailingHeaders(response);
                    Assert.NotNull(trailingHeaders);
                    Assert.Equal(0, trailingHeaders.Count());
                }
        }
Пример #12
0
        public async Task Http2GetAsyncResponseHeadersReadOption_TrailingHeaders_Available()
        {
            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    Task <HttpResponseMessage> sendTask = client.GetAsync(server.Address, HttpCompletionOption.ResponseHeadersRead);

                    Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                    int streamId = await connection.ReadRequestHeaderAsync();

                    // Response header.
                    await connection.SendDefaultResponseHeadersAsync(streamId);

                    // Response data, missing Trailers.
                    await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes));

                    HttpResponseMessage response = await sendTask;
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    // Pending read on the response content.
                    var trailingHeaders = GetTrailingHeaders(response);
                    Assert.True(trailingHeaders == null || trailingHeaders.Count() == 0);

                    Stream stream = await response.Content.ReadAsStreamAsync(TestAsync);

                    Byte[] data = new Byte[100];
                    await stream.ReadAsync(data, 0, data.Length);

                    // Intermediate test - haven't reached stream EOF yet.
                    trailingHeaders = GetTrailingHeaders(response);
                    Assert.True(trailingHeaders == null || trailingHeaders.Count() == 0);

                    // Finish data stream and write out trailing headers.
                    await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes));

                    await connection.SendResponseHeadersAsync(streamId, endStream : true, isTrailingHeader : true, headers : TrailingHeaders);

                    // Read data until EOF is reached
                    while (stream.Read(data, 0, data.Length) != 0)
                    {
                        ;
                    }

                    trailingHeaders = GetTrailingHeaders(response);
                    Assert.Equal(TrailingHeaders.Count, trailingHeaders.Count());
                    Assert.Contains("amazingtrailer", trailingHeaders.GetValues("MyCoolTrailerHeader"));
                    Assert.Contains("World", trailingHeaders.GetValues("Hello"));

                    // Read when already zero. Trailers shouldn't be changed.
                    stream.Read(data, 0, data.Length);

                    trailingHeaders = GetTrailingHeaders(response);
                    Assert.Equal(TrailingHeaders.Count, trailingHeaders.Count());
                }
        }
Пример #13
0
        public async Task ReadAndWriteAfterServerHasSentEndStream_Success()
        {
            TaskCompletionSource <Stream> requestStreamTcs  = new TaskCompletionSource <Stream>(TaskCreationOptions.RunContinuationsAsynchronously);
            TaskCompletionSource <object> completeStreamTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, server.Address);
                    message.Version = new Version(2, 0);
                    message.Content = new StreamingContent(async s =>
                    {
                        await s.WriteAsync(new byte[50]);

                        requestStreamTcs.SetResult(s);

                        await completeStreamTcs.Task;
                    });

                    Task serverActions = RunServer();

                    HttpResponseMessage response = await client.SendAsync(message, HttpCompletionOption.ResponseHeadersRead);

                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    await serverActions;

                    Stream requestStream  = await requestStreamTcs.Task;
                    Stream responseStream = await response.Content.ReadAsStreamAsync();

                    // Successfully because endstream hasn't been read yet.
                    await requestStream.WriteAsync(new byte[50]);

                    byte[] buffer    = new byte[50];
                    int    readCount = await responseStream.ReadAsync(buffer, 0, buffer.Length);

                    Assert.Equal(DataBytes.Length, readCount);

                    readCount = await responseStream.ReadAsync(buffer, 0, buffer.Length);

                    Assert.Equal(0, readCount);

                    async Task RunServer()
                    {
                        Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                        int streamId = await connection.ReadRequestHeaderAsync(expectEndOfStream : false);

                        await connection.SendDefaultResponseHeadersAsync(streamId, endStream : false);

                        await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes, endStream : true));
                    };
                }
        }
Пример #14
0
        public async Task AfterReadResponseServerError_ClientRead()
        {
            TaskCompletionSource <Stream> requestStreamTcs  = new TaskCompletionSource <Stream>(TaskCreationOptions.RunContinuationsAsynchronously);
            TaskCompletionSource <object> completeStreamTcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, server.Address);
                    message.Version = new Version(2, 0);
                    message.Content = new StreamingContent(async s =>
                    {
                        requestStreamTcs.SetResult(s);

                        await completeStreamTcs.Task;
                    });

                    Task <HttpResponseMessage> sendTask = client.SendAsync(message, HttpCompletionOption.ResponseHeadersRead);

                    Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                    Stream requestStream = await requestStreamTcs.Task;
                    await requestStream.WriteAsync(new byte[50]);

                    int streamId = await connection.ReadRequestHeaderAsync(expectEndOfStream : false);

                    Frame frame = await connection.ReadDataFrameAsync();

                    // Response header.
                    await connection.SendDefaultResponseHeadersAsync(streamId);

                    // Response data.
                    await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes, endStream : false));

                    HttpResponseMessage response = await sendTask;
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    Stream responseStream = await response.Content.ReadAsStreamAsync();

                    // Read response data.
                    byte[] buffer    = new byte[1024];
                    int    readCount = await responseStream.ReadAsync(buffer, 0, buffer.Length);

                    Assert.Equal(DataBytes.Length, readCount);

                    // Server sends RST_STREAM.
                    await connection.WriteFrameAsync(new RstStreamFrame(FrameFlags.EndStream, 0, streamId));

                    await Assert.ThrowsAsync <IOException>(() => responseStream.ReadAsync(buffer, 0, buffer.Length));
                }
        }
Пример #15
0
        public async Task ReceiveNoThrowAfterSend_NoSsl(bool useHandler)
        {
            var serverMessage = new byte[] { 4, 5, 6 };
            await Http2LoopbackServer.CreateClientAndServerAsync(async uri =>
            {
                using (var cws = new ClientWebSocket())
                    using (var cts = new CancellationTokenSource(TimeOutMilliseconds))
                    {
                        cws.Options.HttpVersion       = HttpVersion.Version20;
                        cws.Options.HttpVersionPolicy = Http.HttpVersionPolicy.RequestVersionExact;
                        if (useHandler)
                        {
                            var handler = new SocketsHttpHandler();
                            await cws.ConnectAsync(uri, new HttpMessageInvoker(handler), cts.Token);
                        }
                        else
                        {
                            await cws.ConnectAsync(uri, cts.Token);
                        }

                        await cws.SendAsync(new byte[] { 2, 3, 4 }, WebSocketMessageType.Binary, true, cts.Token);

                        var readBuffer = new byte[serverMessage.Length];
                        await cws.ReceiveAsync(readBuffer, cts.Token);
                        Assert.Equal(serverMessage, readBuffer);
                    }
            },
                                                                 async server =>
            {
                Http2LoopbackConnection connection = await server.EstablishConnectionAsync(new SettingsEntry {
                    SettingId = SettingId.EnableConnect, Value = 1
                });
                (int streamId, HttpRequestData requestData) = await connection.ReadAndParseRequestHeaderAsync(readBody: false);
                // send status 200 OK to establish websocket
                await connection.SendResponseHeadersAsync(streamId, endStream: false).ConfigureAwait(false);

                // send reply
                byte binaryMessageType  = 2;
                var prefix              = new byte[] { binaryMessageType, (byte)serverMessage.Length };
                byte[] constructMessage = prefix.Concat(serverMessage).ToArray();
                await connection.SendResponseDataAsync(streamId, constructMessage, endStream: false);
            }, new Http2Options()
            {
                WebSocketEndpoint = true, UseSsl = false
            }
                                                                 );
        }
        public async Task InitialHttp2StreamWindowSize_SentInSettingsFrame()
        {
            const int WindowSize = 123456;

            using Http2LoopbackServer server = Http2LoopbackServer.CreateServer();
            using var handler = CreateHttpClientHandler();
            GetUnderlyingSocketsHttpHandler(handler).InitialHttp2StreamWindowSize = WindowSize;
            using HttpClient client = CreateHttpClient(handler);

            Task <HttpResponseMessage> clientTask = client.GetAsync(server.Address);
            Http2LoopbackConnection    connection = await server.AcceptConnectionAsync().ConfigureAwait(false);

            SettingsFrame clientSettingsFrame = await connection.ReadSettingsAsync().ConfigureAwait(false);

            SettingsEntry entry = clientSettingsFrame.Entries.First(e => e.SettingId == SettingId.InitialWindowSize);

            Assert.Equal(WindowSize, (int)entry.Value);
        }
Пример #17
0
        public async Task Http2GetAsync_MissingTrailer_TrailingHeadersAccepted(bool responseHasContentLength)
        {
            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    Task <HttpResponseMessage> sendTask = client.GetAsync(server.Address);

                    Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                    int streamId = await connection.ReadRequestHeaderAsync();

                    // Response header.
                    if (responseHasContentLength)
                    {
                        await connection.SendResponseHeadersAsync(streamId, endStream : false, headers : new[] { new HttpHeaderData("Content-Length", DataBytes.Length.ToString()) });
                    }
                    else
                    {
                        await connection.SendDefaultResponseHeadersAsync(streamId);
                    }

                    // Response data, missing Trailers.
                    await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes));

                    // Additional trailing header frame.
                    await connection.SendResponseHeadersAsync(streamId, isTrailingHeader : true, headers : TrailingHeaders, endStream : true);

                    HttpResponseMessage response = await sendTask;
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    var trailingHeaders = GetTrailingHeaders(response);
                    Assert.Equal(TrailingHeaders.Count, trailingHeaders.Count());
                    Assert.Contains("amazingtrailer", trailingHeaders.GetValues("MyCoolTrailerHeader"));
                    Assert.Contains("World", trailingHeaders.GetValues("Hello"));
                }
        }
Пример #18
0
        public async Task WriteRequestAfterReadResponse()
        {
            TaskCompletionSource <object> tcs = new TaskCompletionSource <object>(TaskCreationOptions.RunContinuationsAsynchronously);

            using (Http2LoopbackServer server = Http2LoopbackServer.CreateServer())
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage message = new HttpRequestMessage(HttpMethod.Post, server.Address);
                    message.Version = new Version(2, 0);
                    message.Content = new StreamingContent(async s =>
                    {
                        await s.WriteAsync(new byte[50]);

                        await tcs.Task;

                        await s.WriteAsync(new byte[50]);
                    }, length: null);

                    Task <HttpResponseMessage> sendTask = client.SendAsync(message, HttpCompletionOption.ResponseHeadersRead);

                    Http2LoopbackConnection connection = await server.EstablishConnectionAsync();

                    int streamId = await connection.ReadRequestHeaderAsync(expectEndOfStream : false);

                    Frame frame = await connection.ReadDataFrameAsync();

                    // Response header.
                    await connection.SendDefaultResponseHeadersAsync(streamId);

                    // Response data.
                    await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes, endStream : false));

                    HttpResponseMessage response = await sendTask;
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    using Stream responseStream = await response.Content.ReadAsStreamAsync();

                    // Read response data.
                    byte[] buffer    = new byte[1024];
                    int    readCount = await responseStream.ReadAsync(buffer, 0, buffer.Length);

                    Assert.Equal(DataBytes.Length, readCount);

                    // Finish sending request data.
                    tcs.SetResult(null);

                    frame = await connection.ReadDataFrameAsync();

                    // Response data.
                    await connection.WriteFrameAsync(MakeDataFrame(streamId, DataBytes, endStream : true));

                    // Finish reading response data.
                    readCount = await responseStream.ReadAsync(buffer, 0, buffer.Length);

                    Assert.Equal(DataBytes.Length, readCount);

                    readCount = await responseStream.ReadAsync(buffer, 0, buffer.Length);

                    Assert.Equal(0, readCount);
                }
        }
        private async Task EstablishConnectionAsync(Http2LoopbackServer server)
        {
            _connection = await server.EstablishConnectionAsync();

            _incomingFramesTask = ProcessIncomingFramesAsync(_incomingFramesCts.Token);
        }