Esempio n. 1
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);
        }
        public async Task AltSvc_ResponseFrame_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.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);
        }
        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);
        }
Esempio n. 4
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());
                }
        }
Esempio n. 5
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"));
                }
        }
Esempio n. 6
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"));
                }
        }
        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));
        }
        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());
                }
        }
Esempio n. 9
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));
                    };
                }
        }
Esempio n. 10
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));
                }
        }
Esempio n. 11
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"));
                }
        }
Esempio n. 12
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);
                }
        }