public async Task SetProtocols_AfterRequest_ThrowsException()
        {
            if (!BackendSupportsSslConfiguration)
            {
                return;
            }

            using (HttpClientHandler handler = CreateHttpClientHandler())
                using (HttpClient client = CreateHttpClient(handler))
                {
                    handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                    await LoopbackServer.CreateServerAsync(async (server, url) =>
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(
                            server.AcceptConnectionSendResponseAndCloseAsync(),
                            client.GetAsync(url));
                    });

                    Assert.Throws <InvalidOperationException>(() => handler.SslProtocols = SslProtocols.Tls12);
                }
        }
Exemplo n.º 2
0
        public async Task GetAsync_ReceiveSetCookieHeader_CookieRemoved()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = CreateSingleCookieContainer(url);

                using (HttpClient client = CreateHttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK,
                        new HttpHeaderData[] { new HttpHeaderData("Set-Cookie", $"{s_cookieName}=; Expires=Sun, 06 Nov 1994 08:49:37 GMT") },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    CookieCollection collection = handler.CookieContainer.GetCookies(url);
                    Assert.Equal(0, collection.Count);
                }
            });
        }
        public async Task GetAsync_RequestVersion11_Success()
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
                    request.Version            = HttpVersion.Version11;

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(request);
                    Task <List <string> > serverTask           = server.AcceptConnectionSendResponseAndCloseAsync();

                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    var requestLines = await serverTask;
                    Assert.Equal($"GET {url.PathAndQuery} HTTP/1.1", requestLines[0]);
                }
            }, new LoopbackServer.Options {
                StreamWrapper = GetStream
            });
        }
Exemplo n.º 4
0
        public void SendAsync_HttpTracingEnabled_Succeeds()
        {
            RemoteInvoke(async() =>
            {
                using (var listener = new TestEventListener("Microsoft-System-Net-Http", EventLevel.Verbose))
                {
                    var events = new ConcurrentQueue <EventWrittenEventArgs>();
                    await listener.RunWithCallbackAsync(events.Enqueue, async() =>
                    {
                        // Exercise various code paths to get coverage of tracing
                        using (var client = new HttpClient())
                        {
                            // Do a get to a loopback server
                            await LoopbackServer.CreateServerAsync(async(server, url) =>
                            {
                                await TestHelper.WhenAllCompletedOrAnyFailed(
                                    LoopbackServer.ReadRequestAndSendResponseAsync(server),
                                    client.GetAsync(url));
                            });

                            // Do a post to a remote server
                            byte[] expectedData        = Enumerable.Range(0, 20000).Select(i => (byte)i).ToArray();
                            HttpContent content        = new ByteArrayContent(expectedData);
                            content.Headers.ContentMD5 = TestHelper.ComputeMD5Hash(expectedData);
                            using (HttpResponseMessage response = await client.PostAsync(Configuration.Http.RemoteEchoServer, content))
                            {
                                Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            }
                        }
                    });

                    // We don't validate receiving specific events, but rather that we do at least
                    // receive some events, and that enabling tracing doesn't cause other failures
                    // in processing.
                    Assert.InRange(events.Count, 1, int.MaxValue);
                }

                return(SuccessExitCode);
            }).Dispose();
        }
        public async Task GetAsync_SetCookieContainerAndMultipleCookieHeaders_BothCookiesSent()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = CreateSingleCookieContainer(url);

                using (HttpClient client = CreateHttpClient(handler))
                {
                    var requestMessage = new HttpRequestMessage(HttpMethod.Get, url)
                    {
                        Version = UseVersion
                    };
                    requestMessage.Headers.Add("Cookie", "A=1");
                    requestMessage.Headers.Add("Cookie", "B=2");

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(TestAsync, requestMessage);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync();
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    HttpRequestData requestData = await serverTask;
                    string cookieHeaderValue    = GetCookieValue(requestData);

#if NETFRAMEWORK
                    // On .NET Framework multiple Cookie header values are treated as any other header values and are
                    // concatenated using ", " as the separator.  The container cookie is concatenated to
                    // one of these values using the "; " cookie separator.

                    var separators = new string[] { "; ", ", " };
#else
                    var separators = new string[] { "; " };
#endif
                    var cookieValues = cookieHeaderValue.Split(separators, StringSplitOptions.None);
                    Assert.Contains(s_expectedCookieHeaderValue, cookieValues);
                    Assert.Contains("A=1", cookieValues);
                    Assert.Contains("B=2", cookieValues);
                    Assert.Equal(3, cookieValues.Count());
                }
            });
        }
Exemplo n.º 6
0
        public async Task GetAsync_SetCookieContainerAndCookieHeader_BothCookiesSent()
        {
            if (IsNetfxHandler)
            {
                // Netfx handler does not support custom cookie header
                return;
            }

            if (IsCurlHandler)
            {
                // Issue #26983
                // CurlHandler ignores container cookies when custom Cookie header is set.
                return;
            }

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = CreateSingleCookieContainer(url);

                using (HttpClient client = new HttpClient(handler))
                {
                    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
                    requestMessage.Headers.Add("Cookie", s_customCookieHeaderValue);

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(requestMessage);
                    Task <List <string> > serverTask           = LoopbackServer.ReadRequestAndSendResponseAsync(server);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    List <string> requestLines = await serverTask;

                    Assert.Equal(1, requestLines.Count(s => s.StartsWith("Cookie: ")));

                    var cookies = requestLines.Single(s => s.StartsWith("Cookie: ")).Substring(8).Split(new string[] { "; " }, StringSplitOptions.None);
                    Assert.Contains(s_expectedCookieHeaderValue, cookies);
                    Assert.Contains(s_customCookieHeaderValue, cookies);
                    Assert.Equal(2, cookies.Count());
                }
            });
        }
        public async Task GetAsync_NoSpecifiedProtocol_DefaultsToTls12()
        {
            using (HttpClientHandler handler = CreateHttpClientHandler())
                using (HttpClient client = CreateHttpClient(handler))
                {
                    handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;

                    var options = new LoopbackServer.Options {
                        UseSsl = true, SslProtocols = SslProtocols.Tls12
                    };
                    await LoopbackServer.CreateServerAsync(async (server, url) =>
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(
                            client.GetAsync(url),
                            server.AcceptConnectionAsync(async connection =>
                        {
                            Assert.Equal(SslProtocols.Tls12, Assert.IsType <SslStream>(connection.Stream).SslProtocol);
                            await connection.ReadRequestHeaderAndSendResponseAsync();
                        }));
                    }, options);
                }
        }
Exemplo n.º 8
0
        [PlatformSpecific(TestPlatforms.Windows)] // Curl has issues with trailing headers https://github.com/curl/curl/issues/1354
        public async Task GetAsync_TrailingHeaders_Ignored(bool includeTrailerHeader)
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (var client = new HttpClient(handler))
                    {
                        Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                        await TestHelper.WhenAllCompletedOrAnyFailed(
                            getResponseTask,
                            server.AcceptConnectionSendCustomResponseAndCloseAsync(
                                "HTTP/1.1 200 OK\r\n" +
                                "Connection: close\r\n" +
                                "Transfer-Encoding: chunked\r\n" +
                                (includeTrailerHeader ? "Trailer: MyCoolTrailerHeader\r\n" : "") +
                                "\r\n" +
                                "4\r\n" +
                                "data\r\n" +
                                "0\r\n" +
                                "MyCoolTrailerHeader: amazingtrailer\r\n" +
                                "\r\n"));

                        using (HttpResponseMessage response = await getResponseTask)
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            if (includeTrailerHeader)
                            {
                                Assert.Contains("MyCoolTrailerHeader", response.Headers.GetValues("Trailer"));
                            }
                            Assert.False(response.Headers.Contains("MyCoolTrailerHeader"), "Trailer should have been ignored");

                            string data = await response.Content.ReadAsStringAsync();
                            Assert.Contains("data", data);
                            Assert.DoesNotContain("MyCoolTrailerHeader", data);
                            Assert.DoesNotContain("amazingtrailer", data);
                        }
                    }
            });
        }
        public async Task GetAsync_DisallowTls10_AllowTls11_AllowTls12()
        {
            using (var handler = new HttpClientHandler()
            {
                SslProtocols = SslProtocols.Tls11 | SslProtocols.Tls12, ServerCertificateCustomValidationCallback = LoopbackServer.AllowAllCertificates
            })
                using (var client = new HttpClient(handler))
                {
                    if (BackendSupportsSslConfiguration)
                    {
                        LoopbackServer.Options options = new LoopbackServer.Options {
                            UseSsl = true
                        };

                        options.SslProtocols = SslProtocols.Tls;
                        await LoopbackServer.CreateServerAsync(async (server, url) =>
                        {
                            await TestHelper.WhenAllCompletedOrAnyFailed(
                                Assert.ThrowsAsync <IOException>(() => LoopbackServer.ReadRequestAndSendResponseAsync(server, options: options)),
                                Assert.ThrowsAsync <HttpRequestException>(() => client.GetAsync(url)));
                        }, options);

                        foreach (var prot in new[] { SslProtocols.Tls11, SslProtocols.Tls12 })
                        {
                            options.SslProtocols = prot;
                            await LoopbackServer.CreateServerAsync(async (server, url) =>
                            {
                                await TestHelper.WhenAllCompletedOrAnyFailed(
                                    LoopbackServer.ReadRequestAndSendResponseAsync(server, options: options),
                                    client.GetAsync(url));
                            }, options);
                        }
                    }
                    else
                    {
                        await Assert.ThrowsAnyAsync <NotSupportedException>(() => client.GetAsync($"http://{Guid.NewGuid().ToString()}/"));
                    }
                }
        }
        public async Task SetDelegate_ConnectionSucceeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol)
        {
            // Overriding flag for the same reason we skip tests on Catalina
            // On OSX 10.13-10.14 we can override this flag to enable the scenario
            requestOnlyThisProtocol |= PlatformDetection.IsOSX && acceptedProtocol == SslProtocols.Tls;

            using (HttpClientHandler handler = CreateHttpClientHandler())
                using (HttpClient client = CreateHttpClient(handler))
                {
                    handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;

                    if (requestOnlyThisProtocol)
                    {
                        handler.SslProtocols = acceptedProtocol;
                    }
                    else
                    {
                        // Explicitly setting protocols clears implementation default
                        // restrictions on minimum TLS/SSL version
                        // We currently know that some platforms like Debian 10 OpenSSL
                        // will by default block < TLS 1.2
#if !NETFRAMEWORK
                        handler.SslProtocols = SslProtocols.Tls13 | SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
#else
                        handler.SslProtocols = SslProtocols.Tls12 | SslProtocols.Tls11 | SslProtocols.Tls;
#endif
                    }

                    var options = new LoopbackServer.Options {
                        UseSsl = true, SslProtocols = acceptedProtocol
                    };
                    await LoopbackServer.CreateServerAsync(async (server, url) =>
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(
                            server.AcceptConnectionSendResponseAndCloseAsync(),
                            client.GetAsync(url));
                    }, options);
                }
        }
Exemplo n.º 11
0
        public async Task GetAsync_ReceiveInvalidSetCookieHeader_ValidCookiesAdded()
        {
            if (IsNetfxHandler)
            {
                // NetfxHandler incorrectly only processes one valid cookie
                return;
            }

            await LoopbackServerFactory.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();

                using (HttpClient client = new HttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK,
                        new HttpHeaderData[]
                    {
                        new HttpHeaderData("Set-Cookie", "A=1; Path=/;Expires=asdfsadgads"),     // invalid Expires
                        new HttpHeaderData("Set-Cookie", "B=2; Path=/"),
                        new HttpHeaderData("Set-Cookie", "C=3; Path=/")
                    },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    CookieCollection collection = handler.CookieContainer.GetCookies(url);
                    Assert.Equal(2, collection.Count);

                    // Convert to array so we can more easily process contents, since CookieCollection does not implement IEnumerable<Cookie>
                    Cookie[] cookies = new Cookie[3];
                    collection.CopyTo(cookies, 0);

                    Assert.Contains(cookies, c => c.Name == "B" && c.Value == "2");
                    Assert.Contains(cookies, c => c.Name == "C" && c.Value == "3");
                }
            });
        }
Exemplo n.º 12
0
        public async Task GetAsync_RequestVersion0X_ThrowsOr11(int minorVersion)
        {
            Type exceptionType = null;

            if (UseSocketsHttpHandler)
            {
                exceptionType = typeof(NotSupportedException);
            }
            else if (PlatformDetection.IsFullFramework)
            {
                exceptionType = typeof(ArgumentException);
            }

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
                    request.Version            = new Version(0, minorVersion);

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(request);
                    Task <List <string> > serverTask           = server.AcceptConnectionSendResponseAndCloseAsync();

                    if (exceptionType == null)
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);
                        var requestLines = await serverTask;
                        Assert.Equal($"GET {url.PathAndQuery} HTTP/1.1", requestLines[0]);
                    }
                    else
                    {
                        await Assert.ThrowsAsync(exceptionType, (() => TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask)));
                    }
                }
            }, new LoopbackServer.Options {
                StreamWrapper = GetStream_ClientDisconnectOk
            });
        }
        public async Task HttpClientHandler_MultipleAuthenticateHeaders_PicksSupported(string authenticateHeader, string supportedAuth, string unsupportedAuth)
        {
            if (PlatformDetection.IsWindowsNanoServer)
            {
                return;
            }

            var options = new LoopbackServer.Options {
                Domain = Domain, Username = Username, Password = Password
            };
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler     = CreateHttpClientHandler();
                handler.UseDefaultCredentials = false;

                var credentials = new CredentialCache();
                credentials.Add(url, supportedAuth, new NetworkCredential(Username, Password, Domain));
                credentials.Add(url, unsupportedAuth, new NetworkCredential(Username, Password, Domain));

                Task serverTask = server.AcceptConnectionPerformAuthenticationAndCloseAsync(authenticateHeader);
                await TestHelper.WhenAllCompletedOrAnyFailed(CreateAndValidateRequest(handler, url, HttpStatusCode.OK, credentials), serverTask);
            }, options);
        }
        public async Task HttpClientHandler_MultipleAuthenticateHeaders_PicksSupported(string authenticateHeader, string supportedAuth, string unsupportedAuth)
        {
            if (PlatformDetection.IsWindowsNanoServer || (IsCurlHandler && authenticateHeader.Contains("Digest")))
            {
                // TODO: #28065: Fix failing authentication test cases on different httpclienthandlers.
                return;
            }

            var options = new LoopbackServer.Options {
                Domain = Domain, Username = Username, Password = Password
            };
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                StandardSocketsHttpHandler handler = CreateSocketsHttpHandler();

                var credentials = new CredentialCache();
                credentials.Add(url, supportedAuth, new NetworkCredential(Username, Password, Domain));
                credentials.Add(url, unsupportedAuth, new NetworkCredential(Username, Password, Domain));

                Task serverTask = server.AcceptConnectionPerformAuthenticationAndCloseAsync(authenticateHeader);
                await TestHelper.WhenAllCompletedOrAnyFailed(s_createAndValidateRequest(handler, url, HttpStatusCode.OK, credentials), serverTask);
            }, options);
        }
 public async Task GetAsync_NoSpecifiedProtocol_DefaultsToTls12()
 {
     using (var handler = new HttpClientHandler()
     {
         ServerCertificateCustomValidationCallback = LoopbackServer.AllowAllCertificates
     })
         using (var client = new HttpClient(handler))
         {
             var options = new LoopbackServer.Options {
                 UseSsl = true
             };
             await LoopbackServer.CreateServerAsync(async (server, url) =>
             {
                 await TestHelper.WhenAllCompletedOrAnyFailed(
                     client.GetAsync(url),
                     LoopbackServer.AcceptSocketAsync(server, async(s, stream, reader, writer) =>
                 {
                     Assert.Equal(SslProtocols.Tls12, Assert.IsType <SslStream>(stream).SslProtocol);
                     await LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer);
                 }, options));
             }, options);
         }
 }
Exemplo n.º 16
0
        public async Task MaxResponseContentBufferSize_ThrowsIfTooSmallForContent(int maxSize, int contentLength, bool exceptionExpected)
        {
            using (HttpClient client = CreateHttpClient())
            {
                client.MaxResponseContentBufferSize = maxSize;

                await LoopbackServer.CreateServerAsync(async (server, url) =>
                {
                    Task <string> getTask = client.GetStringAsync(url);
                    Task serverTask       = server.AcceptConnectionSendResponseAndCloseAsync(content: new string('s', contentLength));
                    Task bothTasks        = TestHelper.WhenAllCompletedOrAnyFailed(getTask, serverTask);

                    if (exceptionExpected)
                    {
                        await Assert.ThrowsAsync <HttpRequestException>(() => bothTasks);
                    }
                    else
                    {
                        await bothTasks;
                    }
                });
            }
        }
        public async Task GetAsync_ReceiveSetCookieHeader_CookieUpdated()
        {
            const string newCookieValue = "789";

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                StandardSocketsHttpHandler handler = CreateSocketsHttpHandler();
                handler.CookieContainer            = CreateSingleCookieContainer(url);

                using (HttpClient client = new HttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <List <string> > serverTask           = server.AcceptConnectionSendResponseAndCloseAsync(
                        HttpStatusCode.OK, $"Set-Cookie: {s_cookieName}={newCookieValue}\r\n", s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    CookieCollection collection = handler.CookieContainer.GetCookies(url);
                    Assert.Equal(1, collection.Count);
                    Assert.Equal(s_cookieName, collection[0].Name);
                    Assert.Equal(newCookieValue, collection[0].Value);
                }
            });
        }
Exemplo n.º 18
0
        public async Task GetAsync_ReceiveSetCookieHeader_CookieUpdated()
        {
            const string newCookieValue = "789";

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = CreateSingleCookieContainer(url);

                using (HttpClient client = new HttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <List <string> > serverTask           = LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                                                                $"HTTP/1.1 200 Ok\r\nContent-Length: {s_simpleContent.Length}\r\nSet-Cookie: {s_cookieName}={newCookieValue}\r\n\r\n{s_simpleContent}");
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    CookieCollection collection = handler.CookieContainer.GetCookies(url);
                    Assert.Equal(1, collection.Count);
                    Assert.Equal(s_cookieName, collection[0].Name);
                    Assert.Equal(newCookieValue, collection[0].Value);
                }
            });
        }
 public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol)
 {
     using (var handler = new HttpClientHandler()
     {
         ServerCertificateCustomValidationCallback = LoopbackServer.AllowAllCertificates
     })
         using (var client = new HttpClient(handler))
         {
             if (requestOnlyThisProtocol)
             {
                 handler.SslProtocols = acceptedProtocol;
             }
             var options = new LoopbackServer.Options {
                 UseSsl = true, SslProtocols = acceptedProtocol
             };
             await LoopbackServer.CreateServerAsync(async (server, url) =>
             {
                 await TestHelper.WhenAllCompletedOrAnyFailed(
                     LoopbackServer.ReadRequestAndSendResponseAsync(server, options: options),
                     client.GetAsync(url));
             }, options);
         }
 }
Exemplo n.º 20
0
        public async Task GetAsync_ResponseHasNormalLineEndings_Success(string lineEnding)
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
                    Task <List <string> > serverTask           = server.AcceptConnectionSendCustomResponseAndCloseAsync(
                        $"HTTP/1.1 200 OK{lineEnding}Connection: close\r\nDate: {DateTimeOffset.UtcNow:R}{lineEnding}Server: TestServer{lineEnding}Content-Length: 0{lineEnding}{lineEnding}");

                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    using (HttpResponseMessage response = await getResponseTask)
                    {
                        Assert.Equal(200, (int)response.StatusCode);
                        Assert.Equal("OK", response.ReasonPhrase);
                        Assert.Equal("TestServer", response.Headers.Server.ToString());
                    }
                }
            }, new LoopbackServer.Options {
                StreamWrapper = GetStream
            });
        }
        public async Task SetDelegate_ConnectionSucceeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol)
        {
            // Overriding flag for the same reason we skip tests on Catalina
            // On OSX 10.13-10.14 we can override this flag to enable the scenario
            // Issue: #22089
            requestOnlyThisProtocol |= PlatformDetection.IsMacOsHighSierraOrHigher && acceptedProtocol == SslProtocols.Tls;

            if (PlatformDetection.IsMacOsCatalinaOrHigher && acceptedProtocol == SslProtocols.Tls && IsCurlHandler)
            {
                // Issue: #39989
                // When the server uses SslProtocols.Tls, on MacOS, SecureTransport ends up picking a cipher suite
                // for TLS1.2, even though server said it was only using TLS1.0. LibreSsl throws error that
                // wrong cipher is used for TLS1.0.
                throw new SkipTestException("OSX may pick future cipher suites when asked for TLS1.0");
            }

            using (HttpClientHandler handler = CreateHttpClientHandler())
                using (HttpClient client = CreateHttpClient(handler))
                {
                    handler.ServerCertificateCustomValidationCallback = HttpClientHandler.DangerousAcceptAnyServerCertificateValidator;

                    if (requestOnlyThisProtocol)
                    {
                        handler.SslProtocols = acceptedProtocol;
                    }

                    var options = new LoopbackServer.Options {
                        UseSsl = true, SslProtocols = acceptedProtocol
                    };
                    await LoopbackServer.CreateServerAsync(async (server, url) =>
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(
                            server.AcceptConnectionSendResponseAndCloseAsync(),
                            client.GetAsync(url));
                    }, options);
                }
        }
Exemplo n.º 22
0
        public async Task GetAsync_UnknownRequestVersion_ThrowsOrDegradesTo11(int majorVersion, int minorVersion)
        {
            Type exceptionType = null;

            if (PlatformDetection.IsFullFramework)
            {
                exceptionType = typeof(ArgumentException);
            }

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
                    request.Version            = new Version(majorVersion, minorVersion);

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(request);
                    Task <List <string> > serverTask           =
                        LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                       $"HTTP/1.1 200 OK\r\nDate: {DateTimeOffset.UtcNow:R}\r\nContent-Length: 0\r\n\r\n",
                                                                       new LoopbackServer.Options {
                        ResponseStreamWrapper = GetStream_ClientDisconnectOk
                    });

                    if (exceptionType == null)
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);
                        var requestLines = await serverTask;
                        Assert.Equal($"GET {url.PathAndQuery} HTTP/1.1", requestLines[0]);
                    }
                    else
                    {
                        await Assert.ThrowsAsync(exceptionType, (() => TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask)));
                    }
                }
            });
        }
Exemplo n.º 23
0
        public async Task GetAsync_AllowedSSLVersion_Succeeds(SslProtocols acceptedProtocol, bool requestOnlyThisProtocol)
        {
            using (HttpClientHandler handler = CreateHttpClientHandler())
                using (HttpClient client = CreateHttpClient(handler))
                {
                    handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;

                    if (requestOnlyThisProtocol)
                    {
                        handler.SslProtocols = acceptedProtocol;
                    }
                    else
                    {
                        // Explicitly setting protocols clears implementation default
                        // restrictions on minimum TLS/SSL version
                        // We currently know that some platforms like Debian 10 OpenSSL
                        // will by default block < TLS 1.2
#pragma warning disable 0618 // SSL2/3 are deprecated
#if !NETFRAMEWORK
                        handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12 | SslProtocols.Tls13;
#else
                        handler.SslProtocols = SslProtocols.Tls | SslProtocols.Tls11 | SslProtocols.Tls12;
#endif
#pragma warning restore 0618
                    }

                    var options = new LoopbackServer.Options {
                        UseSsl = true, SslProtocols = acceptedProtocol
                    };
                    await LoopbackServer.CreateServerAsync(async (server, url) =>
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(
                            server.AcceptConnectionSendResponseAndCloseAsync(),
                            client.GetAsync(url));
                    }, options);
                }
        }
        public async Task GetAsync_AllowedSSLVersionDiffersFromServer_ThrowsException(
            SslProtocols allowedProtocol, SslProtocols acceptedProtocol, Type exceptedServerException)
        {
            if (!BackendSupportsSslConfiguration)
            {
                return;
            }
            using (HttpClientHandler handler = CreateHttpClientHandler())
                using (var client = new HttpClient(handler))
                {
                    handler.SslProtocols = allowedProtocol;
                    handler.ServerCertificateCustomValidationCallback = LoopbackServer.AllowAllCertificates;

                    var options = new LoopbackServer.Options {
                        UseSsl = true, SslProtocols = acceptedProtocol
                    };
                    await LoopbackServer.CreateServerAsync(async (server, url) =>
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(
                            Assert.ThrowsAsync(exceptedServerException, () => LoopbackServer.ReadRequestAndSendResponseAsync(server, options: options)),
                            Assert.ThrowsAsync <HttpRequestException>(() => client.GetAsync(url)));
                    }, options);
                }
        }
Exemplo n.º 25
0
        public async Task GetAsync_NoPathDefined_CookieAddedWithDefaultPath()
        {
            await LoopbackServerFactory.CreateServerAsync(async (server, serverUrl) =>
            {
                Uri requestUrl            = new Uri(serverUrl, "path/sub");
                HttpClientHandler handler = CreateHttpClientHandler();

                using (HttpClient client = CreateHttpClient(handler))
                {
                    Task <HttpResponseMessage> getResponseTask = client.GetAsync(requestUrl);
                    Task <HttpRequestData> serverTask          = server.HandleRequestAsync(
                        HttpStatusCode.OK,
                        new HttpHeaderData[]
                    {
                        new HttpHeaderData("Set-Cookie", "A=1"),
                    },
                        s_simpleContent);
                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    Cookie cookie = handler.CookieContainer.GetCookies(requestUrl)[0];
                    Assert.Equal("/path", cookie.Path);
                }
            });
        }
Exemplo n.º 26
0
        public async Task GetAsync_ResponseUnknownVersion1X_Success(int responseMinorVersion)
        {
            bool reportAs00 = !UseSocketsHttpHandler;

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
                    request.Version            = HttpVersion.Version11;

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(request);
                    Task <List <string> > serverTask           =
                        server.AcceptConnectionSendCustomResponseAndCloseAsync(
                            $"HTTP/1.{responseMinorVersion} 200 OK\r\nConnection: close\r\nDate: {DateTimeOffset.UtcNow:R}\r\nContent-Length: 0\r\n\r\n");

                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    using (HttpResponseMessage response = await getResponseTask)
                    {
                        if (reportAs00)
                        {
                            Assert.Equal(0, response.Version.Major);
                            Assert.Equal(0, response.Version.Minor);
                        }
                        else
                        {
                            Assert.Equal(1, response.Version.Major);
                            Assert.Equal(responseMinorVersion, response.Version.Minor);
                        }
                    }
                }
            }, new LoopbackServer.Options {
                StreamWrapper = GetStream
            });
        }
Exemplo n.º 27
0
        public async Task GetAsync_RequestVersion11_Success()
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
                    request.Version            = HttpVersion.Version11;

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(request);
                    Task <List <string> > serverTask           =
                        LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                       $"HTTP/1.1 200 OK\r\nDate: {DateTimeOffset.UtcNow:R}\r\nContent-Length: 0\r\n\r\n",
                                                                       new LoopbackServer.Options {
                        ResponseStreamWrapper = GetStream
                    });

                    await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                    var requestLines = await serverTask;
                    Assert.Equal($"GET {url.PathAndQuery} HTTP/1.1", requestLines[0]);
                }
            });
        }
Exemplo n.º 28
0
 private async Task GetAsyncSuccessHelper(string statusLine, int expectedStatusCode, string expectedReason)
 {
     await LoopbackServer.CreateServerAsync(async (server, url) =>
     {
         using (HttpClient client = CreateHttpClient())
         {
             Task <HttpResponseMessage> getResponseTask = client.GetAsync(url);
             await TestHelper.WhenAllCompletedOrAnyFailed(
                 getResponseTask,
                 LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                $"{statusLine}\r\n" +
                                                                $"Date: {DateTimeOffset.UtcNow:R}\r\n" +
                                                                "\r\n",
                                                                new LoopbackServer.Options {
                 ResponseStreamWrapper = GetStream
             }));
             using (HttpResponseMessage response = await getResponseTask)
             {
                 Assert.Equal(expectedStatusCode, (int)response.StatusCode);
                 Assert.Equal(expectedReason, response.ReasonPhrase);
             }
         }
     });
 }
Exemplo n.º 29
0
        public async Task GetAsync_ResponseVersion0X_ThrowsOr10(int responseMinorVersion)
        {
            bool reportAs10 = PlatformDetection.IsFullFramework;

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClient client = CreateHttpClient())
                {
                    HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, url);
                    request.Version            = HttpVersion.Version11;

                    Task <HttpResponseMessage> getResponseTask = client.SendAsync(request);
                    Task <List <string> > serverTask           =
                        LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                       $"HTTP/0.{responseMinorVersion} 200 OK\r\nDate: {DateTimeOffset.UtcNow:R}\r\nContent-Length: 0\r\n\r\n",
                                                                       new LoopbackServer.Options {
                        ResponseStreamWrapper = GetStream_ClientDisconnectOk
                    });

                    if (reportAs10)
                    {
                        await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask);

                        using (HttpResponseMessage response = await getResponseTask)
                        {
                            Assert.Equal(1, response.Version.Major);
                            Assert.Equal(0, response.Version.Minor);
                        }
                    }
                    else
                    {
                        await Assert.ThrowsAsync <HttpRequestException>(async() => await TestHelper.WhenAllCompletedOrAnyFailed(getResponseTask, serverTask));
                    }
                }
            });
        }
Exemplo n.º 30
0
        public async Task Manual_CertificateSentMatchesCertificateReceived_Success(
            int numberOfRequests,
            bool reuseClient)                              // validate behavior with and without connection pooling, which impacts client cert usage
        {
            if (!BackendSupportsCustomCertificateHandling) // can't use [Conditional*] right now as it's evaluated at the wrong time for SocketsHttpHandler
            {
                _output.WriteLine($"Skipping {nameof(Manual_CertificateSentMatchesCertificateReceived_Success)}()");
                return;
            }

            var options = new LoopbackServer.Options {
                UseSsl = true
            };

            Func <X509Certificate2, HttpClient> createClient = (cert) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = delegate { return(true); };
                handler.ClientCertificates.Add(cert);
                Assert.True(handler.ClientCertificates.Contains(cert));
                return(new HttpClient(handler));
            };

            Func <HttpClient, LoopbackServer, Uri, X509Certificate2, Task> makeAndValidateRequest = async(client, server, url, cert) =>
            {
                await TestHelper.WhenAllCompletedOrAnyFailed(
                    client.GetStringAsync(url),
                    server.AcceptConnectionAsync(async connection =>
                {
                    SslStream sslStream = Assert.IsType <SslStream>(connection.Stream);

                    // We can't do Assert.Equal(cert, sslStream.RemoteCertificate) because
                    // on .NET Framework sslStream.RemoteCertificate is always an X509Certificate
                    // object which is not equal to the X509Certificate2 object we use in the tests.
                    // So, we'll just compare a few properties to make sure it's the right certificate.
                    Assert.Equal(cert.Subject, sslStream.RemoteCertificate.Subject);
                    Assert.Equal(cert.Issuer, sslStream.RemoteCertificate.Issuer);

                    await connection.ReadRequestHeaderAndSendResponseAsync(additionalHeaders: "Connection: close\r\n");
                }));
            };

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (X509Certificate2 cert = Configuration.Certificates.GetClientCertificate())
                {
                    if (reuseClient)
                    {
                        using (HttpClient client = createClient(cert))
                        {
                            for (int i = 0; i < numberOfRequests; i++)
                            {
                                await makeAndValidateRequest(client, server, url, cert);

                                GC.Collect();
                                GC.WaitForPendingFinalizers();
                            }
                        }
                    }
                    else
                    {
                        for (int i = 0; i < numberOfRequests; i++)
                        {
                            using (HttpClient client = createClient(cert))
                            {
                                await makeAndValidateRequest(client, server, url, cert);
                            }

                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                        }
                    }
                }
            }, options);
        }