예제 #1
0
        [PlatformSpecific(~TestPlatforms.OSX)] // Not implemented
        public void HttpClientUsesSslCertEnvironmentVariables()
        {
            // We set SSL_CERT_DIR and SSL_CERT_FILE to empty locations.
            // The HttpClient should fail to validate the server certificate.

            var    psi        = new ProcessStartInfo();
            string sslCertDir = GetTestFilePath();

            Directory.CreateDirectory(sslCertDir);
            psi.Environment.Add("SSL_CERT_DIR", sslCertDir);

            string sslCertFile = GetTestFilePath();

            File.WriteAllText(sslCertFile, "");
            psi.Environment.Add("SSL_CERT_FILE", sslCertFile);

            RemoteExecutor.Invoke(async(useSocketsHttpHandlerString, useHttp2String) =>
            {
                const string Url = "https://www.microsoft.com";

                using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString, useHttp2String))
                {
                    await Assert.ThrowsAsync <HttpRequestException>(() => client.GetAsync(Url));
                }
                return(RemoteExecutor.SuccessExitCode);
            }, UseSocketsHttpHandler.ToString(), UseHttp2.ToString(), new RemoteInvokeOptions {
                StartInfo = psi
            }).Dispose();
        }
예제 #2
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();
        }
예제 #3
0
        public void Authentication_UseMultiInterfaceStreamContent_Success()
        {
            RemoteExecutor.Invoke(async(useSocketsHttpHandlerString, useHttp2String) =>
            {
                string username           = "******";
                string password           = "******";
                Uri uri                   = Configuration.Http.RemoteHttp11Server.BasicAuthUriForCreds(userName: username, password: password);
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString, useHttp2String);
                handler.Credentials       = new NetworkCredential(username, password);

                using (HttpClient client = CreateHttpClient(handler, useHttp2String))
                {
                    byte[] postData = Encoding.UTF8.GetBytes("This is data to post.");
                    var stream      = new MultiInterfaceReadOnlyStream(postData);
                    var content     = new MultiInterfaceStreamContent(stream);

                    using (HttpResponseMessage response = await client.PostAsync(uri, content))
                    {
                        Assert.Equal(HttpStatusCode.OK, response.StatusCode);
                        string responseContent = await response.Content.ReadAsStringAsync();
                    }
                }

                return(RemoteExecutor.SuccessExitCode);
            }, UseSocketsHttpHandler.ToString(), UseHttp2.ToString()).Dispose();
        }
예제 #4
0
        public void Authentication_UseStreamContent_Throws()
        {
            RemoteExecutor.Invoke(async(useSocketsHttpHandlerString, useHttp2String) =>
            {
                // This test validates the current limitation of CoreFx's NetFxToWinRtStreamAdapter
                // which throws exceptions when trying to rewind a .NET Stream when it needs to be
                // re-POST'd to the server.
                string username           = "******";
                string password           = "******";
                Uri uri                   = Configuration.Http.RemoteHttp11Server.BasicAuthUriForCreds(userName: username, password: password);
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString, useHttp2String);
                handler.Credentials       = new NetworkCredential(username, password);

                using (HttpClient client = CreateHttpClient(handler, useHttp2String))
                {
                    byte[] postData = Encoding.UTF8.GetBytes("This is data to post.");
                    var stream      = new MemoryStream(postData, false);
                    var content     = new StreamContent(stream);

                    await Assert.ThrowsAsync <HttpRequestException>(() => client.PostAsync(uri, content));
                }

                return(RemoteExecutor.SuccessExitCode);
            }, UseSocketsHttpHandler.ToString(), UseHttp2.ToString()).Dispose();
        }
예제 #5
0
        public void Manual_SelectClientCertificateForRemoteServer_ServerOnlyReceivesValidClientCert(
            int certIndex, HttpStatusCode expectedStatusCode)
        {
            if (!CanTestClientCertificates) // can't use [Conditional*] right now as it's evaluated at the wrong time for SocketsHttpHandler
            {
                _output.WriteLine($"Skipping {nameof(Manual_SelectClientCertificateForRemoteServer_ServerOnlyReceivesValidClientCert)}()");
                return;
            }

            string           useSocketsHttpHandlerString = UseSocketsHttpHandler.ToString();
            string           useHttp2String = UseHttp2.ToString();
            X509Certificate2 clientCert     = null;

            // Get client certificate. RemoteInvoke doesn't allow easy marshaling of complex types.
            // So we have to select the certificate at this point in the test execution.
            if (certIndex == 1)
            {
                // This is a valid client cert since it has an EKU with a ClientAuthentication OID.
                clientCert = Configuration.Certificates.GetClientCertificate();
            }
            else if (certIndex == 2)
            {
                // This is a valid client cert since it has no EKU thus all usages are permitted.
                clientCert = Configuration.Certificates.GetNoEKUCertificate();
            }
            else if (certIndex == 3)
            {
                // This is an invalid client cert since it has an EKU but is missing ClientAuthentication OID.
                clientCert = Configuration.Certificates.GetServerCertificate();
            }

            Assert.NotNull(clientCert);

            HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString, useHttp2String);

            handler.ClientCertificates.Add(clientCert);
            using (HttpClient client = CreateHttpClient(handler, useHttp2String))
            {
                var request = new HttpRequestMessage();
                request.RequestUri = new Uri(Configuration.Http.EchoClientCertificateRemoteServer);

                // Issue #35239. Force HTTP/1.1.
                request.Version = new Version(1, 1);
                HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult(); // need a 4-arg overload of RemoteInvoke that returns a Task
                Assert.Equal(expectedStatusCode, response.StatusCode);

                if (expectedStatusCode == HttpStatusCode.OK)
                {
                    string body         = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); // need a 4-arg overload of RemoteInvoke that returns a Task
                    byte[] bytes        = Convert.FromBase64String(body);
                    var    receivedCert = new X509Certificate2(bytes);
                    Assert.Equal(clientCert, receivedCert);
                }
            }
        }
        public async Task ProxySetViaEnvironmentVariable_DefaultProxyCredentialsUsed(bool useProxy)
        {
            const string ExpectedUsername = "******";
            const string ExpectedPassword = "******";

            LoopbackServer.Options options = new LoopbackServer.Options {
                IsProxy = true, Username = ExpectedUsername, Password = ExpectedPassword
            };

            await LoopbackServer.CreateServerAsync(async (proxyServer, proxyUri) =>
            {
                // libcurl will read a default proxy from the http_proxy environment variable.  Ensure that when it does,
                // our default proxy credentials are used.  To avoid messing up anything else in this process, we run the
                // test in another process.
                var psi = new ProcessStartInfo();
                Task <List <string> > proxyTask = null;

                if (useProxy)
                {
                    proxyTask = proxyServer.AcceptConnectionPerformAuthenticationAndCloseAsync("Proxy-Authenticate: Basic realm=\"NetCore\"\r\n");
                    psi.Environment.Add("http_proxy", $"http://{proxyUri.Host}:{proxyUri.Port}");
                }

                RemoteExecutor.Invoke(async(useProxyString, useSocketsHttpHandlerString, useHttp2String) =>
                {
                    using (HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString, useHttp2String))
                        using (HttpClient client = CreateHttpClient(handler, useHttp2String))
                        {
                            var creds = new NetworkCredential(ExpectedUsername, ExpectedPassword);
                            handler.DefaultProxyCredentials = creds;
                            handler.UseProxy = bool.Parse(useProxyString);

                            HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer);
                            // Correctness of user and password is done in server part.
                            Assert.True(response.StatusCode == HttpStatusCode.OK);
                        }
                    return(RemoteExecutor.SuccessExitCode);
                }, useProxy.ToString(), UseSocketsHttpHandler.ToString(), UseHttp2.ToString(), new RemoteInvokeOptions {
                    StartInfo = psi
                }).Dispose();
                if (useProxy)
                {
                    await proxyTask;
                }
            }, options);
        }
예제 #7
0
        public void Authentication_UseMultiInterfaceNonRewindableStreamContent_Throws()
        {
            RemoteExecutor.Invoke(async(useSocketsHttpHandlerString, useHttp2String) =>
            {
                string username           = "******";
                string password           = "******";
                Uri uri                   = Configuration.Http.RemoteHttp11Server.BasicAuthUriForCreds(userName: username, password: password);
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString, useHttp2String);
                handler.Credentials       = new NetworkCredential(username, password);

                using (HttpClient client = CreateHttpClient(handler, useHttp2String))
                {
                    byte[] postData = Encoding.UTF8.GetBytes("This is data to post.");
                    var stream      = new MultiInterfaceNonRewindableReadOnlyStream(postData);
                    var content     = new MultiInterfaceStreamContent(stream);

                    await Assert.ThrowsAsync <HttpRequestException>(() => client.PostAsync(uri, content));
                }
            }, UseSocketsHttpHandler.ToString(), UseHttp2.ToString()).Dispose();
        }
        public async Task UseCallback_BadCertificate_ExpectedPolicyErrors(string url, SslPolicyErrors expectedErrors)
        {
            const int SEC_E_BUFFER_TOO_SMALL = unchecked ((int)0x80090321);

            if (!ClientSupportsDHECipherSuites)
            {
                return;
            }

            try
            {
                await UseCallback_BadCertificate_ExpectedPolicyErrors_Helper(url, UseHttp2.ToString(), expectedErrors);
            }
            catch (HttpRequestException e) when(e.InnerException?.GetType().Name == "WinHttpException" &&
                                                e.InnerException.HResult == SEC_E_BUFFER_TOO_SMALL &&
                                                !PlatformDetection.IsWindows10Version1607OrGreater)
            {
                // Testing on old Windows versions can hit https://github.com/dotnet/corefx/issues/7812
                // Ignore SEC_E_BUFFER_TOO_SMALL error on such cases.
            }
        }
예제 #9
0
        public async Task UseCallback_BadCertificate_ExpectedPolicyErrors(string url, SslPolicyErrors expectedErrors)
        {
            const int SEC_E_BUFFER_TOO_SMALL = unchecked ((int)0x80090321);

            if (!BackendSupportsCustomCertificateHandlingAndClientSupportsDHECipherSuites)
            {
                return;
            }

            try
            {
                if (PlatformDetection.IsUap)
                {
                    // UAP HTTP stack caches connections per-process. This causes interference when these tests run in
                    // the same process as the other tests. Each test needs to be isolated to its own process.
                    // See dicussion: https://github.com/dotnet/corefx/issues/21945
                    RemoteExecutor.Invoke((remoteUrl, remoteExpectedErrors, useSocketsHttpHandlerString, useHttp2String) =>
                    {
                        UseCallback_BadCertificate_ExpectedPolicyErrors_Helper(
                            remoteUrl,
                            useSocketsHttpHandlerString,
                            useHttp2String,
                            (SslPolicyErrors)Enum.Parse(typeof(SslPolicyErrors), remoteExpectedErrors)).Wait();

                        return(RemoteExecutor.SuccessExitCode);
                    }, url, expectedErrors.ToString(), UseSocketsHttpHandler.ToString(), UseHttp2.ToString()).Dispose();
                }
                else
                {
                    await UseCallback_BadCertificate_ExpectedPolicyErrors_Helper(url, UseSocketsHttpHandler.ToString(), UseHttp2.ToString(), expectedErrors);
                }
            }
            catch (HttpRequestException e) when(e.InnerException?.GetType().Name == "WinHttpException" &&
                                                e.InnerException.HResult == SEC_E_BUFFER_TOO_SMALL &&
                                                !PlatformDetection.IsWindows10Version1607OrGreater)
            {
                // Testing on old Windows versions can hit https://github.com/dotnet/corefx/issues/7812
                // Ignore SEC_E_BUFFER_TOO_SMALL error on such cases.
            }
        }
예제 #10
0
        public void Manual_SelectClientCertificateForRemoteServer_ServerOnlyReceivesValidClientCert(
            int certIndex, HttpStatusCode expectedStatusCode)
        {
            if (!CanTestClientCertificates) // can't use [Conditional*] right now as it's evaluated at the wrong time for SocketsHttpHandler
            {
                _output.WriteLine($"Skipping {nameof(Manual_SelectClientCertificateForRemoteServer_ServerOnlyReceivesValidClientCert)}()");
                return;
            }

            // UAP HTTP stack caches connections per-process. This causes interference when these tests run in
            // the same process as the other tests. Each test needs to be isolated to its own process.
            // See dicussion: https://github.com/dotnet/corefx/issues/21945
            RemoteExecutor.Invoke((certIndexString, expectedStatusCodeString, useSocketsHttpHandlerString, useHttp2String) =>
            {
                X509Certificate2 clientCert = null;

                // Get client certificate. RemoteInvoke doesn't allow easy marshaling of complex types.
                // So we have to select the certificate at this point in the test execution.
                if (certIndexString == "1")
                {
                    // This is a valid client cert since it has an EKU with a ClientAuthentication OID.
                    clientCert = Configuration.Certificates.GetClientCertificate();
                }
                else if (certIndexString == "2")
                {
                    // This is a valid client cert since it has no EKU thus all usages are permitted.
                    clientCert = Configuration.Certificates.GetNoEKUCertificate();
                }
                else if (certIndexString == "3")
                {
                    // This is an invalid client cert since it has an EKU but is missing ClientAuthentication OID.
                    clientCert = Configuration.Certificates.GetServerCertificate();
                }

                Assert.NotNull(clientCert);

                var statusCode            = (HttpStatusCode)Enum.Parse(typeof(HttpStatusCode), expectedStatusCodeString);
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString, useHttp2String);
                handler.ClientCertificates.Add(clientCert);
                using (HttpClient client = CreateHttpClient(handler, useHttp2String))
                {
                    var request        = new HttpRequestMessage();
                    request.RequestUri = new Uri(Configuration.Http.EchoClientCertificateRemoteServer);

                    // Issue #35239. Force HTTP/1.1.
                    request.Version = new Version(1, 1);
                    HttpResponseMessage response = client.SendAsync(request).GetAwaiter().GetResult(); // need a 4-arg overload of RemoteInvoke that returns a Task
                    Assert.Equal(statusCode, response.StatusCode);

                    if (statusCode == HttpStatusCode.OK)
                    {
                        string body      = response.Content.ReadAsStringAsync().GetAwaiter().GetResult(); // need a 4-arg overload of RemoteInvoke that returns a Task
                        byte[] bytes     = Convert.FromBase64String(body);
                        var receivedCert = new X509Certificate2(bytes);
                        Assert.Equal(clientCert, receivedCert);
                    }

                    return(RemoteExecutor.SuccessExitCode);
                }
            }, certIndex.ToString(), expectedStatusCode.ToString(), UseSocketsHttpHandler.ToString(), UseHttp2.ToString()).Dispose();
        }