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);
         }
 }
        public async Task HttpClientHandler_Authentication_Succeeds(string authenticateHeader, bool result)
        {
            if (PlatformDetection.IsWindowsNanoServer || (IsCurlHandler && authenticateHeader.ToLowerInvariant().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) =>
            {
                string serverAuthenticateHeader = $"WWW-Authenticate: {authenticateHeader}\r\n";
                HttpClientHandler handler       = CreateHttpClientHandler();
                Task serverTask = result ?
                                  server.AcceptConnectionPerformAuthenticationAndCloseAsync(serverAuthenticateHeader) :
                                  server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized, serverAuthenticateHeader);

                await TestHelper.WhenAllCompletedOrAnyFailedWithTimeout(TestHelper.PassingTestTimeoutMilliseconds,
                                                                        s_createAndValidateRequest(handler, url, result ? HttpStatusCode.OK : HttpStatusCode.Unauthorized, s_credentials), serverTask);
            }, options);
        }
        private static void CreateServerAndGet(HttpClient client, HttpCompletionOption completionOption, string responseText)
        {
            LoopbackServer.CreateServerAsync((server, url) =>
            {
                Task <HttpResponseMessage> getAsync = client.GetAsync(url, completionOption);

                server.AcceptConnectionAsync(connection =>
                {
                    while (!string.IsNullOrEmpty(connection.Reader.ReadLine()))
                    {
                        ;
                    }

                    connection.Writer.Write(responseText);
                    connection.Socket.Shutdown(SocketShutdown.Send);

                    return(Task.CompletedTask);
                }).GetAwaiter().GetResult();

                getAsync.GetAwaiter().GetResult().Dispose();
                return(Task.CompletedTask);
            }).GetAwaiter().GetResult();
        }
Beispiel #4
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
            });
        }
        private static void CreateServerAndGet(HttpClient client, HttpCompletionOption completionOption, string responseText)
        {
            LoopbackServer.CreateServerAsync((server, url) =>
            {
                Task <HttpResponseMessage> getAsync = client.GetAsync(url, completionOption);

                LoopbackServer.AcceptSocketAsync(server, (s, stream, reader, writer) =>
                {
                    while (!string.IsNullOrEmpty(reader.ReadLine()))
                    {
                        ;
                    }

                    writer.Write(responseText);
                    s.Shutdown(SocketShutdown.Send);

                    return(Task.FromResult <List <string> >(null));
                }).GetAwaiter().GetResult();

                getAsync.GetAwaiter().GetResult().Dispose();
                return(Task.CompletedTask);
            }).GetAwaiter().GetResult();
        }
Beispiel #6
0
        public async Task ProxiedRequest_DefaultPort_PortStrippedOffInUri(string host)
        {
            string addressUri         = $"http://{host}:80/";
            string expectedAddressUri = $"http://{host}/";
            bool   connectionAccepted = false;

            await LoopbackServer.CreateClientAndServerAsync(async proxyUri =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        handler.Proxy = new WebProxy(proxyUri);
                        try { await client.GetAsync(addressUri); } catch { }
                    }
            }, server => server.AcceptConnectionAsync(async connection =>
            {
                connectionAccepted    = true;
                List <string> headers = await connection.ReadRequestHeaderAndSendResponseAsync();
                Assert.Contains($"GET {expectedAddressUri} HTTP/1.1", headers);
            }));

            Assert.True(connectionAccepted);
        }
        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);
        }
Beispiel #8
0
        public async Task AutomaticOrManual_DoesntFailRegardlessOfWhetherClientCertsAreAvailable(ClientCertificateOption mode)
        {
            using (HttpClientHandler handler = CreateHttpClientHandler())
                using (HttpClient client = CreateHttpClient(handler))
                {
                    handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                    handler.ClientCertificateOptions = mode;

                    await LoopbackServer.CreateServerAsync(async server =>
                    {
                        Task clientTask = client.GetStringAsync(server.Address);
                        Task serverTask = server.AcceptConnectionAsync(async connection =>
                        {
                            SslStream sslStream = Assert.IsType <SslStream>(connection.Stream);
                            await connection.ReadRequestHeaderAndSendResponseAsync();
                        });

                        await new Task[] { clientTask, serverTask }.WhenAllOrAnyFailed();
                    }, new LoopbackServer.Options {
                        UseSsl = true
                    });
                }
        }
Beispiel #9
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           = 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);
                }
            });
        }
Beispiel #10
0
 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);
         }
 }
Beispiel #11
0
        private static async Task CreateServerAndPostAsync(HttpClient client, int numBytes, string responseText)
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                var content = new ByteArrayContent(new byte[numBytes]);
                Task <HttpResponseMessage> postAsync = client.PostAsync(url, content);

                await server.AcceptConnectionAsync(async connection =>
                {
                    byte[] postData = new byte[numBytes];
                    while (!string.IsNullOrEmpty(await connection.ReadLineAsync().ConfigureAwait(false)))
                    {
                        ;
                    }
                    Assert.Equal(numBytes, await connection.ReadBlockAsync(postData, 0, numBytes));

                    await connection.Writer.WriteAsync(responseText).ConfigureAwait(false);
                    connection.Socket.Shutdown(SocketShutdown.Send);
                });

                (await postAsync.ConfigureAwait(false)).Dispose();
            });
        }
Beispiel #12
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 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);
                }
        }
Beispiel #14
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 ThresholdExceeded_ThrowsException(string responseHeaders, int?maxResponseHeadersLength, bool shouldSucceed)
        {
            if (IsCurlHandler)
            {
                // libcurl often fails with out of memory errors
                return;
            }

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (StandardSocketsHttpHandler handler = CreateSocketsHttpHandler())
                    using (var client = new HttpClient(handler))
                    {
                        if (maxResponseHeadersLength.HasValue)
                        {
                            handler.MaxResponseHeadersLength = maxResponseHeadersLength.Value;
                        }
                        Task <HttpResponseMessage> getAsync = client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);

                        await server.AcceptConnectionAsync(async connection =>
                        {
                            Task serverTask = connection.ReadRequestHeaderAndSendCustomResponseAsync(responseHeaders);

                            if (shouldSucceed)
                            {
                                (await getAsync).Dispose();
                                await serverTask;
                            }
                            else
                            {
                                await Assert.ThrowsAsync <HttpRequestException>(() => getAsync);
                                try { await serverTask; } catch { }
                            }
                        });
                    }
            });
        }
Beispiel #16
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)));
                    }
                }
            });
        }
        public async Task PreAuthenticate_AuthenticatedUrl_ThenTryDifferentUrl_SendsAuthHeaderOnlyIfPrefixMatches(
            string originalRelativeUri, string secondRelativeUri, bool expectedAuthHeader)
        {
            const string AuthResponse = "WWW-Authenticate: Basic realm=\"hello\"\r\n";

            await LoopbackServer.CreateClientAndServerAsync(async uri =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        client.DefaultRequestHeaders.ConnectionClose = true; // for simplicity of not needing to know every handler's pooling policy
                        handler.PreAuthenticate = true;
                        handler.Credentials     = s_credentials;

                        Assert.Equal("hello world 1", await client.GetStringAsync(new Uri(uri, originalRelativeUri)));
                        Assert.Equal("hello world 2", await client.GetStringAsync(new Uri(uri, secondRelativeUri)));
                    }
            },
                                                            async server =>
            {
                List <string> headers = await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized, AuthResponse);
                Assert.All(headers, header => Assert.DoesNotContain("Authorization", header));

                headers = await server.AcceptConnectionSendResponseAndCloseAsync(content: "hello world 1");
                Assert.Contains(headers, header => header.Contains("Authorization"));

                headers = await server.AcceptConnectionSendResponseAndCloseAsync(content: "hello world 2");
                if (expectedAuthHeader)
                {
                    Assert.Contains(headers, header => header.Contains("Authorization"));
                }
                else
                {
                    Assert.All(headers, header => Assert.DoesNotContain("Authorization", header));
                }
            });
        }
        public async Task GetAsync_DontDisposeResponse_EventuallyUnblocksWaiters()
        {
            if (!UseSocketsHttpHandler)
            {
                // Issue #27067. Hang.
                return;
            }

            await LoopbackServer.CreateServerAsync(async (server, uri) =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = new HttpClient(handler))
                    {
                        handler.MaxConnectionsPerServer = 1;

                        // Let server handle two requests.
                        const string Response = "HTTP/1.1 200 OK\r\nContent-Length: 26\r\n\r\nabcdefghijklmnopqrstuvwxyz";
                        Task serverTask1      = LoopbackServer.ReadRequestAndSendResponseAsync(server, Response);
                        Task serverTask2      = LoopbackServer.ReadRequestAndSendResponseAsync(server, Response);

                        // Make first request and drop the response, not explicitly disposing of it.
                        void MakeAndDropRequest() => client.GetAsync(uri, HttpCompletionOption.ResponseHeadersRead); // separated out to enable GC of response
                        MakeAndDropRequest();

                        // A second request should eventually succeed, once the first one is cleaned up.
                        Task <HttpResponseMessage> secondResponse = client.GetAsync(uri);
                        Assert.True(SpinWait.SpinUntil(() =>
                        {
                            GC.Collect();
                            GC.WaitForPendingFinalizers();
                            return(secondResponse.IsCompleted);
                        }, 30 * 1000), "Expected second response to have completed");

                        await new[] { serverTask1, serverTask2, secondResponse }.WhenAllOrAnyFailed();
                    }
            });
        }
        public async Task GetAsyncWithRedirect_SetCookieContainer_CorrectCookiesSent()
        {
            const string path1 = "/foo";
            const string path2 = "/bar";

            await LoopbackServer.CreateServerAndClientAsync(async url =>
            {
                Uri url1      = new Uri(url, path1);
                Uri url2      = new Uri(url, path2);
                Uri unusedUrl = new Uri(url, "/unused");

                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = new CookieContainer();
                handler.CookieContainer.Add(url1, new Cookie("cookie1", "value1"));
                handler.CookieContainer.Add(url2, new Cookie("cookie2", "value2"));
                handler.CookieContainer.Add(unusedUrl, new Cookie("cookie3", "value3"));

                using (HttpClient client = new HttpClient(handler))
                {
                    await client.GetAsync(url1);
                }
            },
                                                            async server =>
            {
                List <string> request1Lines = await LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                                                   $"HTTP/1.1 302 Found\r\nContent-Length: 0\r\nLocation: {path2}\r\nConnection: close\r\n\r\n");

                Assert.Contains($"Cookie: cookie1=value1", request1Lines);
                Assert.Equal(1, request1Lines.Count(s => s.StartsWith("Cookie:")));

                List <string> request2Lines = await LoopbackServer.ReadRequestAndSendResponseAsync(server,
                                                                                                   $"HTTP/1.1 200 OK\r\nContent-Length: {s_simpleContent.Length}\r\n\r\n{s_simpleContent}");

                Assert.Contains($"Cookie: cookie2=value2", request2Lines);
                Assert.Equal(1, request2Lines.Count(s => s.StartsWith("Cookie:")));
            });
        }
Beispiel #20
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]);
                }
            });
        }
Beispiel #21
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);
             }
         }
     });
 }
Beispiel #22
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));
                    }
                }
            });
        }
        public async Task PreAuthenticate_SuccessfulBasicButThenFails_DoesntLoopInfinitely()
        {
            await LoopbackServer.CreateClientAndServerAsync(async uri =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        client.DefaultRequestHeaders.ConnectionClose = true; // for simplicity of not needing to know every handler's pooling policy
                        handler.PreAuthenticate = true;
                        handler.Credentials     = s_credentials;

                        // First two requests: initially without auth header, then with
                        Assert.Equal("hello world", await client.GetStringAsync(uri));

                        // Attempt preauth, and when that fails, give up.
                        using (HttpResponseMessage resp = await client.GetAsync(uri))
                        {
                            Assert.Equal(HttpStatusCode.Unauthorized, resp.StatusCode);
                        }
                    }
            },
                                                            async server =>
            {
                // First request, no auth header, challenge Basic
                List <string> headers = headers = await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized, "WWW-Authenticate: Basic realm=\"hello\"\r\n");
                Assert.All(headers, header => Assert.DoesNotContain("Authorization", header));

                // Second request, contains Basic auth header
                headers = await server.AcceptConnectionSendResponseAndCloseAsync(content: "hello world");
                Assert.Contains(headers, header => header.Contains("Authorization"));

                // Third request, contains Basic auth header but challenges anyway
                headers = headers = await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Unauthorized, "WWW-Authenticate: Basic realm=\"hello\"\r\n");
                Assert.Contains(headers, header => header.Contains("Authorization"));
            });
        }
        public async Task GetAsync_AddMultipleCookieHeaders_CookiesSent()
        {
            if (IsNetfxHandler)
            {
                // Netfx handler does not support custom cookie header
                return;
            }

            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                using (HttpClient client = new HttpClient(handler))
                {
                    HttpRequestMessage requestMessage = new HttpRequestMessage(HttpMethod.Get, url);
                    requestMessage.Headers.Add("Cookie", "A=1");
                    requestMessage.Headers.Add("Cookie", "B=2");
                    requestMessage.Headers.Add("Cookie", "C=3");

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

                    List <string> requestLines = await serverTask;

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

                    // Multiple Cookie header values are treated as any other header values and are
                    // concatenated using ", " as the separator.

                    var cookieValues = requestLines.Single(s => s.StartsWith("Cookie: ")).Substring(8).Split(new string[] { ", " }, StringSplitOptions.None);
                    Assert.Contains("A=1", cookieValues);
                    Assert.Contains("B=2", cookieValues);
                    Assert.Contains("C=3", cookieValues);
                    Assert.Equal(3, cookieValues.Count());
                }
            });
        }
        public async Task GetAsyncWithRedirect_SetCookieContainer_CorrectCookiesSent()
        {
            const string path1 = "/foo";
            const string path2 = "/bar";

            await LoopbackServer.CreateClientAndServerAsync(async url =>
            {
                Uri url1      = new Uri(url, path1);
                Uri url2      = new Uri(url, path2);
                Uri unusedUrl = new Uri(url, "/unused");

                HttpClientHandler handler = CreateHttpClientHandler();
                handler.CookieContainer   = new CookieContainer();
                handler.CookieContainer.Add(url1, new Cookie("cookie1", "value1"));
                handler.CookieContainer.Add(url2, new Cookie("cookie2", "value2"));
                handler.CookieContainer.Add(unusedUrl, new Cookie("cookie3", "value3"));

                using (HttpClient client = new HttpClient(handler))
                {
                    client.DefaultRequestHeaders.ConnectionClose = true; // to avoid issues with connection pooling
                    await client.GetAsync(url1);
                }
            },
                                                            async server =>
            {
                List <string> request1Lines = await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.Found, $"Location: {path2}\r\n");

                Assert.Contains($"Cookie: cookie1=value1", request1Lines);
                Assert.Equal(1, request1Lines.Count(s => s.StartsWith("Cookie:")));

                List <string> request2Lines = await server.AcceptConnectionSendResponseAndCloseAsync(content: s_simpleContent);

                Assert.Contains($"Cookie: cookie2=value2", request2Lines);
                Assert.Equal(1, request2Lines.Count(s => s.StartsWith("Cookie:")));
            });
        }
Beispiel #26
0
        public async Task ProxyTunnelRequest_OriginServerSendsProxyAuthChallenge_NoProxyAuthPerformed()
        {
            if (IsWinHttpHandler)
            {
                return;
            }

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create())
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.Proxy = new WebProxy(proxyServer.Uri)
                {
                    Credentials = ConstructCredentials(new NetworkCredential("username", "password"), proxyServer.Uri, BasicAuth, true)
                };
                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                using (HttpClient client = CreateHttpClient(handler))
                {
                    var options = new LoopbackServer.Options {
                        UseSsl = true
                    };
                    await LoopbackServer.CreateServerAsync(async (server, uri) =>
                    {
                        Assert.Equal(proxyServer.Uri, handler.Proxy.GetProxy(uri));

                        Task <HttpResponseMessage> clientTask = client.GetAsync(uri);
                        await server.AcceptConnectionSendResponseAndCloseAsync(statusCode: HttpStatusCode.ProxyAuthenticationRequired, additionalHeaders: "Proxy-Authenticate: Basic").WaitAsync(TestHelper.PassingTestTimeout);
                        using (var response = await clientTask.WaitAsync(TestHelper.PassingTestTimeout))
                        {
                            Assert.Equal(HttpStatusCode.ProxyAuthenticationRequired, response.StatusCode);
                        }
                    }, options).WaitAsync(TestHelper.PassingTestTimeout);
                }

                Assert.Contains("CONNECT", proxyServer.Requests[0].RequestLine);
            }
        }
Beispiel #27
0
        public async Task ProxyTunnelRequest_GetAsync_Success()
        {
            if (IsWinHttpHandler)
            {
                return;
            }

            const string Content = "Hello world";

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create())
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.Proxy = new WebProxy(proxyServer.Uri);
                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                using (HttpClient client = CreateHttpClient(handler))
                {
                    var options = new LoopbackServer.Options {
                        UseSsl = true
                    };
                    await LoopbackServer.CreateServerAsync(async (server, uri) =>
                    {
                        Assert.Equal(proxyServer.Uri, handler.Proxy.GetProxy(uri));

                        Task <HttpResponseMessage> clientTask = client.GetAsync(uri);
                        await server.AcceptConnectionSendResponseAndCloseAsync(content: Content);
                        using (var response = await clientTask)
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            Assert.Equal(Content, await response.Content.ReadAsStringAsync());
                        }
                    }, options);
                }

                Assert.Contains("CONNECT", proxyServer.Requests[0].RequestLine);
            }
        }
Beispiel #28
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
            });
        }
Beispiel #29
0
        public async Task InfiniteSingleHeader_ThrowsException()
        {
            await LoopbackServer.CreateServerAsync(async (server, url) =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        Task <HttpResponseMessage> getAsync = client.GetAsync(url, HttpCompletionOption.ResponseHeadersRead);
                        await server.AcceptConnectionAsync(async connection =>
                        {
                            var cts         = new CancellationTokenSource();
                            Task serverTask = Task.Run(async delegate
                            {
                                await connection.ReadRequestHeaderAndSendCustomResponseAsync("HTTP/1.1 200 OK\r\nContent-Length: 0\r\nMyInfiniteHeader: ");
                                try
                                {
                                    while (!cts.IsCancellationRequested)
                                    {
                                        await connection.Writer.WriteAsync(new string('s', 16000));
                                        await Task.Delay(1);
                                    }
                                }
                                catch { }
                            });

                            Exception e = await Assert.ThrowsAsync <HttpRequestException>(() => getAsync);
                            cts.Cancel();
                            if (UseSocketsHttpHandler)
                            {
                                Assert.Contains((handler.MaxResponseHeadersLength * 1024).ToString(), e.ToString());
                            }
                            await serverTask;
                        });
                    }
            });
        }
        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);
                }
        }