コード例 #1
0
        public void Proxy_UseEnvironmentVariableToSetSystemProxy_RequestGoesThruProxy()
        {
            if (!UseSocketsHttpHandler)
            {
                throw new SkipTestException("Test needs SocketsHttpHandler");
            }

            RemoteExecutor.Invoke(async(useSocketsHttpHandlerString, useHttp2String) =>
            {
                var options = new LoopbackProxyServer.Options {
                    AddViaRequestHeader = true
                };
                using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
                {
                    Environment.SetEnvironmentVariable("http_proxy", proxyServer.Uri.AbsoluteUri.ToString());

                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString, useHttp2String))
                        using (HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer))
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            string body = await response.Content.ReadAsStringAsync();
                            Assert.Contains(proxyServer.ViaHeader, body);
                        }

                    return(RemoteExecutor.SuccessExitCode);
                }
            }, UseSocketsHttpHandler.ToString(), UseHttp2.ToString()).Dispose();
        }
コード例 #2
0
        public async Task AuthenticatedProxyTunnelRequest_PostAsyncWithNoCreds_Throws()
        {
            if (IsWinHttpHandler)
            {
                return;
            }

            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes = AuthenticationSchemes.Basic,
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.Proxy = new WebProxy(proxyServer.Uri);
                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                using (HttpClient client = CreateHttpClient(handler))
                {
                    HttpRequestException e = await Assert.ThrowsAnyAsync <HttpRequestException>(async() => await client.PostAsync("https://nosuchhost.invalid", new StringContent(content)));

                    Assert.Contains("407", e.Message);
                }
            }
        }
コード例 #3
0
        public async Task AuthenticatedProxiedRequest_GetAsyncWithCreds_Success(NetworkCredential cred, bool wrapCredsInCache, bool connectionCloseAfter407)
        {
            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes   = cred != null ? AuthenticationSchemes.Basic : AuthenticationSchemes.None,
                ConnectionCloseAfter407 = connectionCloseAfter407
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        handler.Proxy = new WebProxy(proxyServer.Uri)
                        {
                            Credentials = ConstructCredentials(cred, proxyServer.Uri, BasicAuth, wrapCredsInCache)
                        };

                        using (HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer))
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            TestHelper.VerifyResponseBody(
                                await response.Content.ReadAsStringAsync(),
                                response.Content.Headers.ContentMD5,
                                false,
                                null);

                            ValidateProxyBasicAuthentication(proxyServer, cred);
                        }
                    }
        }
コード例 #4
0
        public async Task UseCallback_HaveNoCredsAndUseAuthenticatedCustomProxyAndPostToSecureServer_ProxyAuthenticationRequiredStatusCode()
        {
            if (!BackendSupportsCustomCertificateHandling)
            {
                return;
            }

            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes   = AuthenticationSchemes.Basic,
                ConnectionCloseAfter407 = true
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.Proxy = new WebProxy(proxyServer.Uri);
                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                using (HttpClient client = CreateHttpClient(handler))
                    using (HttpResponseMessage response = await client.PostAsync(
                               Configuration.Http.SecureRemoteEchoServer,
                               new StringContent("This is a test")))
                    {
                        Assert.Equal(HttpStatusCode.ProxyAuthenticationRequired, response.StatusCode);
                    }
            }
        }
コード例 #5
0
        public async Task UseCallback_HaveCredsAndUseAuthenticatedCustomProxyAndPostToSecureServer_Success()
        {
            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes   = AuthenticationSchemes.Basic,
                ConnectionCloseAfter407 = true
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                handler.Proxy = new WebProxy(proxyServer.Uri)
                {
                    Credentials = new NetworkCredential("rightusername", "rightpassword")
                };

                const string content = "This is a test";

                using (HttpClient client = CreateHttpClient(handler))
                    using (HttpResponseMessage response = await client.PostAsync(
                               Configuration.Http.SecureRemoteEchoServer,
                               new StringContent(content)))
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        TestHelper.VerifyResponseBody(
                            responseContent,
                            response.Content.Headers.ContentMD5,
                            false,
                            content);
                    }
            }
        }
コード例 #6
0
        public async Task Proxy_BypassFalse_GetRequestGoesThroughCustomProxy(ICredentials creds, bool wrapCredsInCache)
        {
            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes = creds != null ? AuthenticationSchemes.Basic : AuthenticationSchemes.None
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                const string BasicAuth = "Basic";
                if (wrapCredsInCache)
                {
                    Assert.IsAssignableFrom <NetworkCredential>(creds);
                    var cache = new CredentialCache();
                    cache.Add(proxyServer.Uri, BasicAuth, (NetworkCredential)creds);
                    creds = cache;
                }

                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (var client = new HttpClient(handler))
                    {
                        handler.Proxy = new WebProxy(proxyServer.Uri)
                        {
                            Credentials = creds
                        };

                        using (HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer))
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            TestHelper.VerifyResponseBody(
                                await response.Content.ReadAsStringAsync(),
                                response.Content.Headers.ContentMD5,
                                false,
                                null);

                            if (options.AuthenticationSchemes != AuthenticationSchemes.None)
                            {
                                NetworkCredential nc = creds?.GetCredential(proxyServer.Uri, BasicAuth);
                                Assert.NotNull(nc);
                                string expectedAuth =
                                    string.IsNullOrEmpty(nc.Domain) ? $"{nc.UserName}:{nc.Password}" :
                                    $"{nc.Domain}\\{nc.UserName}:{nc.Password}";
                                _output.WriteLine($"expectedAuth={expectedAuth}");
                                string expectedAuthHash = Convert.ToBase64String(Encoding.UTF8.GetBytes(expectedAuth));

                                // Check last request to proxy server. CurlHandler will use pre-auth for Basic proxy auth,
                                // so there might only be 1 request received by the proxy server. Other handlers won't use
                                // pre-auth for proxy so there would be 2 requests.
                                int requestCount = proxyServer.Requests.Count;
                                _output.WriteLine($"proxyServer.Requests.Count={requestCount}");
                                Assert.Equal(BasicAuth, proxyServer.Requests[requestCount - 1].AuthorizationHeaderValueScheme);
                                Assert.Equal(expectedAuthHash, proxyServer.Requests[requestCount - 1].AuthorizationHeaderValueToken);
                            }
                        }
                    }
            }
        }
コード例 #7
0
        public async Task AuthProxy__ValidCreds_ProxySendsRequestToServer(
            AuthenticationSchemes proxyAuthScheme,
            bool secureServer,
            bool proxyClosesConnectionAfterFirst407Response)
        {
            if (PlatformDetection.IsWindowsNanoServer && IsWinHttpHandler && proxyAuthScheme == AuthenticationSchemes.Digest)
            {
                // WinHTTP doesn't support Digest very well and is disabled on Nano.
                return;
            }

            if (!PlatformDetection.IsWindows &&
                (proxyAuthScheme == AuthenticationSchemes.Negotiate || proxyAuthScheme == AuthenticationSchemes.Ntlm))
            {
                // CI machines don't have GSSAPI module installed and will fail with error from
                // System.Net.Security.NegotiateStreamPal.AcquireCredentialsHandle():
                //        "GSSAPI operation failed with error - An invalid status code was supplied
                //         Configuration file does not specify default realm)."
                return;
            }

            Uri serverUri = secureServer ? Configuration.Http.SecureRemoteEchoServer : Configuration.Http.RemoteEchoServer;

            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes   = proxyAuthScheme,
                ConnectionCloseAfter407 = proxyClosesConnectionAfterFirst407Response
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        handler.Proxy             = new WebProxy(proxyServer.Uri);
                        handler.Proxy.Credentials = new NetworkCredential("username", "password");
                        using (HttpResponseMessage response = await client.GetAsync(serverUri))
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            TestHelper.VerifyResponseBody(
                                await response.Content.ReadAsStringAsync(),
                                response.Content.Headers.ContentMD5,
                                false,
                                null);
                        }
                    }
            }
        }
コード例 #8
0
        public async Task Proxy_HaveNoCredsAndUseAuthenticatedCustomProxy_ProxyAuthenticationRequiredStatusCode()
        {
            var options = new LoopbackProxyServer.Options {
                AuthenticationSchemes = AuthenticationSchemes.Basic
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.Proxy = new WebProxy(proxyServer.Uri);
                using (var client = new HttpClient(handler))
                    using (HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer))
                    {
                        Assert.Equal(HttpStatusCode.ProxyAuthenticationRequired, response.StatusCode);
                    }
            }
        }
        public async Task UseCallback_HaveCredsAndUseAuthenticatedCustomProxyAndPostToSecureServer_Success()
        {
            if (!BackendSupportsCustomCertificateHandling)
            {
                return;
            }

            if (IsWinHttpHandler && PlatformDetection.IsWindows7)
            {
                // Issue #27612
                return;
            }

            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes   = AuthenticationSchemes.Basic,
                ConnectionCloseAfter407 = true
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                StandardSocketsHttpHandler handler = CreateSocketsHttpHandler();
                handler.SslOptions.RemoteCertificateValidationCallback = delegate { return(true); };
                handler.Proxy = new WebProxy(proxyServer.Uri)
                {
                    Credentials = new NetworkCredential("rightusername", "rightpassword")
                };

                const string content = "This is a test";

                using (var client = new HttpClient(handler))
                    using (HttpResponseMessage response = await client.PostAsync(
                               Configuration.Http.SecureRemoteEchoServer,
                               new StringContent(content)))
                    {
                        string responseContent = await response.Content.ReadAsStringAsync();

                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        TestHelper.VerifyResponseBody(
                            responseContent,
                            response.Content.Headers.ContentMD5,
                            false,
                            content);
                    }
            }
        }
コード例 #10
0
        public async Task Proxy_DomainJoinedProxyServerUsesKerberos_Success(Uri server)
        {
            // We skip the test unless it is running on a Windows client machine. That is because only Windows
            // automatically registers an SPN for HTTP/<hostname> of the machine. This will enable Kerberos to properly
            // work with the loopback proxy server.
            if (!PlatformDetection.IsWindows || !PlatformDetection.IsNotWindowsNanoServer)
            {
                throw new SkipTestException("Test can only run on domain joined Windows client machine");
            }

            var options = new LoopbackProxyServer.Options {
                AuthenticationSchemes = AuthenticationSchemes.Negotiate
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        // Use 'localhost' DNS name for loopback proxy server (instead of IP address) so that the SPN will
                        // get calculated properly to use Kerberos.
                        _output.WriteLine(proxyServer.Uri.AbsoluteUri.ToString());
                        handler.Proxy = new WebProxy("localhost", proxyServer.Uri.Port)
                        {
                            Credentials = DomainCredential
                        };

                        using (HttpResponseMessage response = await client.GetAsync(server))
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                            int requestCount = proxyServer.Requests.Count;

                            // We expect 2 requests to the proxy server. One without the 'Proxy-Authorization' header and
                            // one with the header.
                            Assert.Equal(2, requestCount);
                            Assert.Equal("Negotiate", proxyServer.Requests[requestCount - 1].AuthorizationHeaderValueScheme);

                            // Base64 tokens that use SPNEGO protocol start with 'Y'. NTLM tokens start with 'T'.
                            Assert.Equal('Y', proxyServer.Requests[requestCount - 1].AuthorizationHeaderValueToken[0]);
                        }
                    }
            }
        }
コード例 #11
0
        public void Proxy_UseEnvironmentVariableToSetSystemProxy_RequestGoesThruProxy()
        {
            RemoteExecutor.Invoke(async(useVersionString) =>
            {
                var options = new LoopbackProxyServer.Options {
                    AddViaRequestHeader = true
                };
                using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
                {
                    Environment.SetEnvironmentVariable("http_proxy", proxyServer.Uri.AbsoluteUri.ToString());

                    using (HttpClient client = CreateHttpClient(useVersionString))
                        using (HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer))
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            string body = await response.Content.ReadAsStringAsync();
                            Assert.Contains(proxyServer.ViaHeader, body);
                        }
                }
            }, UseVersion.ToString()).Dispose();
        }
コード例 #12
0
        public async Task AuthenticatedProxyTunnelRequest_PostAsyncWithCreds_Success(NetworkCredential cred, bool wrapCredsInCache, bool connectionCloseAfter407)
        {
            if (IsWinHttpHandler)
            {
                return;
            }

            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes   = cred != null ? AuthenticationSchemes.Basic : AuthenticationSchemes.None,
                ConnectionCloseAfter407 = connectionCloseAfter407
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
                using (HttpClientHandler handler = CreateHttpClientHandler())
                    using (HttpClient client = CreateHttpClient(handler))
                    {
                        handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                        handler.Proxy = new WebProxy(proxyServer.Uri)
                        {
                            Credentials = ConstructCredentials(cred, proxyServer.Uri, BasicAuth, wrapCredsInCache)
                        };

                        using (HttpResponseMessage response = await client.PostAsync(Configuration.Http.SecureRemoteEchoServer, new StringContent(content)))
                        {
                            string responseContent = await response.Content.ReadAsStringAsync();

                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            TestHelper.VerifyResponseBody(
                                responseContent,
                                response.Content.Headers.ContentMD5,
                                false,
                                content);

                            ValidateProxyBasicAuthentication(proxyServer, cred);
                        }
                    }
        }
コード例 #13
0
        public async Task AuthenticatedProxyTunnelRequest_PostAsyncWithNoCreds_ProxyAuthenticationRequiredStatusCode()
        {
            if (IsWinHttpHandler)
            {
                return;
            }

            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes = AuthenticationSchemes.Basic,
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                HttpClientHandler handler = CreateHttpClientHandler();
                handler.Proxy = new WebProxy(proxyServer.Uri);
                handler.ServerCertificateCustomValidationCallback = TestHelper.AllowAllCertificates;
                using (HttpClient client = CreateHttpClient(handler))
                    using (HttpResponseMessage response = await client.PostAsync(Configuration.Http.SecureRemoteEchoServer, new StringContent(content)))
                    {
                        Assert.Equal(HttpStatusCode.ProxyAuthenticationRequired, response.StatusCode);
                    }
            }
        }
コード例 #14
0
        public async Task AuthProxy__ValidCreds_ProxySendsRequestToServer(
            AuthenticationSchemes proxyAuthScheme,
            bool secureServer,
            bool proxyClosesConnectionAfterFirst407Response)
        {
            if (PlatformDetection.IsFedora && IsCurlHandler)
            {
                // CurlHandler seems unstable on Fedora26 and returns error
                // "System.Net.Http.CurlException : Failure when receiving data from the peer".
                return;
            }

            if (PlatformDetection.IsWindowsNanoServer && IsWinHttpHandler && proxyAuthScheme == AuthenticationSchemes.Digest)
            {
                // WinHTTP doesn't support Digest very well and is disabled on Nano.
                return;
            }

            if (PlatformDetection.IsFullFramework &&
                (proxyAuthScheme == AuthenticationSchemes.Negotiate || proxyAuthScheme == AuthenticationSchemes.Ntlm))
            {
                // Skip due to bug in .NET Framework with Windows auth and proxy tunneling.
                return;
            }

            if (!PlatformDetection.IsWindows &&
                (proxyAuthScheme == AuthenticationSchemes.Negotiate || proxyAuthScheme == AuthenticationSchemes.Ntlm))
            {
                // CI machines don't have GSSAPI module installed and will fail with error from
                // System.Net.Security.NegotiateStreamPal.AcquireCredentialsHandle():
                //        "GSSAPI operation failed with error - An invalid status code was supplied
                //         Configuration file does not specify default realm)."
                return;
            }

            if (IsCurlHandler && proxyAuthScheme != AuthenticationSchemes.Basic)
            {
                // Issue #27870 curl HttpHandler can only do basic auth to proxy.
                return;
            }

            Uri serverUri = secureServer ? Configuration.Http.SecureRemoteEchoServer : Configuration.Http.RemoteEchoServer;

            var options = new LoopbackProxyServer.Options
            {
                AuthenticationSchemes   = proxyAuthScheme,
                ConnectionCloseAfter407 = proxyClosesConnectionAfterFirst407Response
            };

            using (LoopbackProxyServer proxyServer = LoopbackProxyServer.Create(options))
            {
                using (StandardSocketsHttpHandler handler = CreateSocketsHttpHandler())
                    using (var client = new HttpClient(handler))
                    {
                        handler.Proxy             = new WebProxy(proxyServer.Uri);
                        handler.Proxy.Credentials = new NetworkCredential("username", "password");
                        using (HttpResponseMessage response = await client.GetAsync(serverUri))
                        {
                            Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                            TestHelper.VerifyResponseBody(
                                await response.Content.ReadAsStringAsync(),
                                response.Content.Headers.ContentMD5,
                                false,
                                null);
                        }
                    }
            }
        }