public void Authentication_UseStreamContent_Throws()
        {
            RemoteInvoke(async useSocketsHttpHandlerString =>
            {
                // 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.BasicAuthUriForCreds(secure: false, userName: username, password: password);
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString);
                handler.Credentials       = new NetworkCredential(username, password);

                using (var client = new HttpClient(handler))
                {
                    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(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
        public void Authentication_UseMultiInterfaceStreamContent_Success()
        {
            RemoteInvoke(async useSocketsHttpHandlerString =>
            {
                string username           = "******";
                string password           = "******";
                Uri uri                   = Configuration.Http.BasicAuthUriForCreds(secure: false, userName: username, password: password);
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString);
                handler.Credentials       = new NetworkCredential(username, password);

                using (var client = new HttpClient(handler))
                {
                    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(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#3
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();
        }
示例#4
0
        public void Authentication_UseMemoryStreamNotVisibleBufferContent_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 MemoryStream(postData, 0, postData.Length, false, false);
                    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();
        }
示例#5
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();
        }
        public void Manual_SendClientCertificateWithServerAuthEKUToRemoteServer_Forbidden()
        {
            if (UseSocketsHttpHandler)
            {
                // TODO #23128: SocketsHttpHandler is currently sending out client certificates when it shouldn't.
                return;
            }

            if (!CanTestClientCertificates) // can't use [Conditional*] right now as it's evaluated at the wrong time for SocketsHttpHandler
            {
                _output.WriteLine($"Skipping {nameof(Manual_SendClientCertificateWithServerAuthEKUToRemoteServer_Forbidden)}()");
                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
            RemoteInvoke(async useSocketsHttpHandlerString =>
            {
                var cert = Configuration.Certificates.GetServerCertificate();
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString);
                handler.ClientCertificates.Add(cert);
                using (var client = new HttpClient(handler))
                {
                    HttpResponseMessage response = await client.GetAsync(Configuration.Http.EchoClientCertificateRemoteServer);
                    Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);

                    return(SuccessExitCode);
                }
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#7
0
        public void Manual_SendClientCertificateWithNoEKUToRemoteServer_OK()
        {
            if (!CanTestClientCertificates) // can't use [Conditional*] right now as it's evaluated at the wrong time for SocketsHttpHandler
            {
                _output.WriteLine($"Skipping {nameof(Manual_SendClientCertificateWithNoEKUToRemoteServer_OK)}()");
                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
            RemoteInvoke(async useSocketsHttpHandlerString =>
            {
                var cert = Configuration.Certificates.GetNoEKUCertificate();
                HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString);
                handler.ClientCertificates.Add(cert);
                using (var client = new HttpClient(handler))
                {
                    HttpResponseMessage response = await client.GetAsync(Configuration.Http.EchoClientCertificateRemoteServer);
                    Assert.Equal(HttpStatusCode.OK, response.StatusCode);

                    string body      = await response.Content.ReadAsStringAsync();
                    byte[] bytes     = Convert.FromBase64String(body);
                    var receivedCert = new X509Certificate2(bytes);
                    Assert.Equal(cert, receivedCert);

                    return(SuccessExitCode);
                }
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#8
0
        public void SendAsync_ExpectedDiagnosticSynchronousExceptionActivityLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool exceptionLogged           = false;
                bool activityStopLogged        = false;
                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Stop"))
                    {
                        Assert.NotNull(kvp.Value);
                        GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");
                        var requestStatus = GetPropertyValueFromAnonymousTypeInstance <TaskStatus>(kvp.Value, "RequestTaskStatus");
                        Assert.Equal(TaskStatus.Faulted, requestStatus);

                        activityStopLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Exception"))
                    {
                        Assert.NotNull(kvp.Value);
                        GetPropertyValueFromAnonymousTypeInstance <Exception>(kvp.Value, "Exception");

                        exceptionLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable();
                    using (HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString))
                        using (HttpClient client = new HttpClient(handler))
                        {
                            if (bool.Parse(useSocketsHttpHandlerString))
                            {
                                // Forces a synchronous exception for SocketsHttpHandler
                                HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, $"http://{Guid.NewGuid()}.com");
                                request.Version            = new Version(0, 0);

                                Assert.ThrowsAsync <NotSupportedException>(() => client.SendAsync(request)).Wait();
                            }
                            else
                            {
                                // Forces a synchronous exception for WinHttpHandler
                                handler.UseCookies      = true;
                                handler.CookieContainer = null;

                                Assert.ThrowsAsync <InvalidOperationException>(() => client.GetAsync($"http://{Guid.NewGuid()}.com")).Wait();
                            }
                        }
                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    WaitForTrue(() => activityStopLogged, TimeSpan.FromSeconds(1),
                                "Response with exception was not logged within 1 second timeout.");
                    Assert.True(exceptionLogged, "Exception was not logged");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#9
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);
                    }
                }
            }, certIndex.ToString(), expectedStatusCode.ToString(), UseSocketsHttpHandler.ToString(), UseHttp2.ToString()).Dispose();
        }
示例#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;
            }

            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);
                }
            }
        }
示例#11
0
        public void SendAsync_ExpectedDiagnosticSourceNoLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool requestLogged       = false;
                bool responseLogged      = false;
                bool activityStartLogged = false;
                bool activityStopLogged  = false;

                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.Request"))
                    {
                        requestLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Response"))
                    {
                        responseLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Start"))
                    {
                        activityStartLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Stop"))
                    {
                        activityStopLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        LoopbackServer.CreateServerAsync(async(server, url) =>
                        {
                            Task <List <string> > requestLines = LoopbackServer.AcceptSocketAsync(server,
                                                                                                  (s, stream, reader, writer) => LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer));
                            Task <HttpResponseMessage> response = client.GetAsync(url);
                            await Task.WhenAll(response, requestLines);

                            AssertNoHeadersAreInjected(requestLines.Result);
                            response.Result.Dispose();
                        }).Wait();
                    }

                    Assert.False(requestLogged, "Request was logged while logging disabled.");
                    Assert.False(activityStartLogged, "HttpRequestOut.Start was logged while logging disabled.");
                    WaitForFalse(() => responseLogged, TimeSpan.FromSeconds(1), "Response was logged while logging disabled.");
                    Assert.False(activityStopLogged, "HttpRequestOut.Stop was logged while logging disabled.");
                }
                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#12
0
        public void SendAsync_ExpectedDiagnosticSourceActivityLoggingDoesNotOverwriteHeader()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool activityStartLogged = false;
                bool activityStopLogged  = false;

                Activity parentActivity = new Activity("parent");
                parentActivity.AddBaggage("correlationId", Guid.NewGuid().ToString());
                parentActivity.Start();

                string customRequestIdHeader   = "|foo.bar.";
                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Start"))
                    {
                        var request = GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");
                        request.Headers.Add("Request-Id", customRequestIdHeader);

                        activityStartLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Stop"))
                    {
                        var request = GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");
                        Assert.Single(request.Headers.GetValues("Request-Id"));
                        Assert.Equal(customRequestIdHeader, request.Headers.GetValues("Request-Id").Single());
                        activityStopLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable();
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        client.GetAsync(Configuration.Http.RemoteEchoServer).Result.Dispose();
                    }

                    Assert.True(activityStartLogged, "HttpRequestOut.Start was not logged.");

                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    WaitForTrue(() => activityStopLogged, TimeSpan.FromSeconds(1), "HttpRequestOut.Stop was not logged within 1 second timeout.");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#13
0
        public void SendAsync_ExpectedDiagnosticSourceNewAndDeprecatedEventsLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool requestLogged       = false;
                bool responseLogged      = false;
                bool activityStartLogged = false;
                bool activityStopLogged  = false;

                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.Request"))
                    {
                        requestLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Response"))
                    {
                        responseLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Start"))
                    {
                        activityStartLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Stop"))
                    {
                        activityStopLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable();
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        client.GetAsync(Configuration.Http.RemoteEchoServer).Result.Dispose();
                    }

                    Assert.True(activityStartLogged, "HttpRequestOut.Start was not logged.");
                    Assert.True(requestLogged, "Request was not logged.");
                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    WaitForTrue(() => activityStopLogged, TimeSpan.FromSeconds(1), "HttpRequestOut.Stop was not logged within 1 second timeout.");
                    Assert.True(responseLogged, "Response was not logged.");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
        [ActiveIssue(25640, TestPlatforms.Windows)] // TODO It should be enabled for SocketsHttpHandler on all platforms
        public void ProxySetViaEnvironmentVariable_DefaultProxyCredentialsUsed(bool useProxy)
        {
            int port = 0;
            Task <LoopbackGetRequestHttpProxy.ProxyResult> proxyTask = null;

            if (useProxy)
            {
                proxyTask = LoopbackGetRequestHttpProxy.StartAsync(out port, requireAuth: true, expectCreds: true);
            }

            const string ExpectedUsername = "******";
            const string ExpectedPassword = "******";

            // 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();

            psi.Environment.Add("http_proxy", $"http://localhost:{port}");
            RemoteInvoke((useProxyString, useSocketsHttpHandlerString) =>
            {
                using (HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString))
                    using (var client = new HttpClient(handler))
                    {
                        var creds = new NetworkCredential(ExpectedUsername, ExpectedPassword);
                        handler.DefaultProxyCredentials = creds;
                        handler.UseProxy = bool.Parse(useProxyString);

                        Task <HttpResponseMessage> responseTask = client.GetAsync(Configuration.Http.RemoteEchoServer);
                        Task <string> responseStringTask        = responseTask.ContinueWith(t =>
                        {
                            using (t.Result) return(t.Result.Content.ReadAsStringAsync());
                        }, TaskScheduler.Default).Unwrap();
                        Task.WaitAll(responseTask, responseStringTask);

                        TestHelper.VerifyResponseBody(responseStringTask.Result, responseTask.Result.Content.Headers.ContentMD5, false, null);
                    }
                return(SuccessExitCode);
            }, useProxy.ToString(), UseSocketsHttpHandler.ToString(), new RemoteInvokeOptions {
                StartInfo = psi
            }).Dispose();

            if (useProxy)
            {
                Assert.Equal($"{ExpectedUsername}:{ExpectedPassword}", proxyTask.Result.AuthenticationHeaderValue);
            }
        }
示例#15
0
        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}");
                }

                RemoteInvoke(async(useProxyString, useSocketsHttpHandlerString) =>
                {
                    using (HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString))
                        using (var client = new HttpClient(handler))
                        {
                            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(SuccessExitCode);
                }, useProxy.ToString(), UseSocketsHttpHandler.ToString(), new RemoteInvokeOptions {
                    StartInfo = psi
                }).Dispose();
                if (useProxy)
                {
                    await proxyTask;
                }
            }, options);
        }
示例#16
0
        public void SendAsync_ExpectedDiagnosticSourceUrlFilteredActivityLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool activityStartLogged = false;
                bool activityStopLogged  = false;

                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Start"))
                    {
                        activityStartLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Stop"))
                    {
                        activityStopLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable((s, r, _) =>
                    {
                        if (s.StartsWith("System.Net.Http.HttpRequestOut"))
                        {
                            var request = r as HttpRequestMessage;
                            if (request != null)
                            {
                                return(!request.RequestUri.Equals(Configuration.Http.RemoteEchoServer));
                            }
                        }
                        return(true);
                    });
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        client.GetAsync(Configuration.Http.RemoteEchoServer).Result.Dispose();
                    }
                    Assert.False(activityStartLogged, "HttpRequestOut.Start was logged while URL disabled.");
                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    Assert.False(activityStopLogged, "HttpRequestOut.Stop was logged while URL disabled.");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#17
0
        public void SendAsync_ExpectedDiagnosticCancelledActivityLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool cancelLogged = false;
                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key == "System.Net.Http.HttpRequestOut.Stop")
                    {
                        Assert.NotNull(kvp.Value);
                        GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");
                        var status = GetPropertyValueFromAnonymousTypeInstance <TaskStatus>(kvp.Value, "RequestTaskStatus");
                        Assert.Equal(TaskStatus.Canceled, status);
                        Volatile.Write(ref cancelLogged, true);
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable();
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        LoopbackServer.CreateServerAsync(async(server, url) =>
                        {
                            CancellationTokenSource tcs = new CancellationTokenSource();
                            Task request = LoopbackServer.AcceptSocketAsync(server,
                                                                            (s, stream, reader, writer) =>
                            {
                                tcs.Cancel();
                                return(LoopbackServer.ReadWriteAcceptedAsync(s, reader, writer));
                            });
                            Task response = client.GetAsync(url, tcs.Token);
                            await Assert.ThrowsAnyAsync <Exception>(() => TestHelper.WhenAllCompletedOrAnyFailed(response, request));
                        }).Wait();
                    }
                }
                // Poll with a timeout since logging response is not synchronized with returning a response.
                WaitForTrue(() => Volatile.Read(ref cancelLogged), TimeSpan.FromSeconds(1),
                            "Cancellation was not logged within 1 second timeout.");
                diagnosticListenerObserver.Disable();

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#18
0
        public void SendAsync_HttpTracingEnabled_Succeeds(bool useSsl)
        {
            RemoteInvoke(async(useSocketsHttpHandlerString, useSslString) =>
            {
                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 (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                        {
                            // Do a get to a loopback server
                            await LoopbackServer.CreateServerAsync(async(server, url) =>
                            {
                                await TestHelper.WhenAllCompletedOrAnyFailed(
                                    server.AcceptConnectionSendResponseAndCloseAsync(),
                                    client.GetAsync(url));
                            });

                            // Do a post to a remote server
                            byte[] expectedData        = Enumerable.Range(0, 20000).Select(i => unchecked ((byte)i)).ToArray();
                            Uri remoteServer           = bool.Parse(useSslString) ? Configuration.Http.SecureRemoteEchoServer : Configuration.Http.RemoteEchoServer;
                            var content                = new ByteArrayContent(expectedData);
                            content.Headers.ContentMD5 = TestHelper.ComputeMD5Hash(expectedData);
                            using (HttpResponseMessage response = await client.PostAsync(remoteServer, 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.DoesNotContain(events, ev => ev.EventId == 0); // make sure there are no event source error messages
                    Assert.InRange(events.Count, 1, int.MaxValue);
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString(), useSsl.ToString()).Dispose();
        }
示例#19
0
        public void SendAsync_ExpectedDiagnosticExceptionLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool exceptionLogged           = false;
                bool responseLogged            = false;
                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.Response"))
                    {
                        Assert.NotNull(kvp.Value);
                        var requestStatus = GetPropertyValueFromAnonymousTypeInstance <TaskStatus>(kvp.Value, "RequestTaskStatus");
                        Assert.Equal(TaskStatus.Faulted, requestStatus);

                        responseLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Exception"))
                    {
                        Assert.NotNull(kvp.Value);
                        GetPropertyValueFromAnonymousTypeInstance <Exception>(kvp.Value, "Exception");

                        exceptionLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable(s => !s.Contains("HttpRequestOut"));
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        Assert.ThrowsAsync <HttpRequestException>(() => client.GetAsync($"http://{Guid.NewGuid()}.com")).Wait();
                    }
                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    WaitForTrue(() => responseLogged, TimeSpan.FromSeconds(1),
                                "Response with exception was not logged within 1 second timeout.");
                    Assert.True(exceptionLogged, "Exception was not logged");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#20
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, 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.
            }
        }
示例#22
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.
            }
        }
示例#23
0
        public void SendAsync_ExpectedDiagnosticSourceActivityLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool requestLogged       = false;
                bool responseLogged      = false;
                bool activityStartLogged = false;
                bool activityStopLogged  = false;
                bool exceptionLogged     = false;

                Activity parentActivity = new Activity("parent");
                parentActivity.AddBaggage("correlationId", Guid.NewGuid().ToString());
                parentActivity.AddBaggage("moreBaggage", Guid.NewGuid().ToString());
                parentActivity.AddTag("tag", "tag"); //add tag to ensure it is not injected into request
                parentActivity.Start();

                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.Request"))
                    {
                        requestLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Response"))
                    {
                        responseLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Exception"))
                    {
                        exceptionLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Start"))
                    {
                        Assert.NotNull(kvp.Value);
                        Assert.NotNull(Activity.Current);
                        Assert.Equal(parentActivity, Activity.Current.Parent);
                        GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");

                        activityStartLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Stop"))
                    {
                        Assert.NotNull(kvp.Value);
                        Assert.NotNull(Activity.Current);
                        Assert.Equal(parentActivity, Activity.Current.Parent);
                        Assert.True(Activity.Current.Duration != TimeSpan.Zero);
                        GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");
                        GetPropertyValueFromAnonymousTypeInstance <HttpResponseMessage>(kvp.Value, "Response");
                        var requestStatus = GetPropertyValueFromAnonymousTypeInstance <TaskStatus>(kvp.Value, "RequestTaskStatus");
                        Assert.Equal(TaskStatus.RanToCompletion, requestStatus);

                        activityStopLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable(s => s.Contains("HttpRequestOut"));
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        LoopbackServer.CreateServerAsync(async(server, url) =>
                        {
                            Task <List <string> > requestLines  = server.AcceptConnectionSendResponseAndCloseAsync();
                            Task <HttpResponseMessage> response = client.GetAsync(url);
                            await Task.WhenAll(response, requestLines);

                            AssertHeadersAreInjected(requestLines.Result, parentActivity);
                            response.Result.Dispose();
                        }).Wait();
                    }

                    Assert.True(activityStartLogged, "HttpRequestOut.Start was not logged.");
                    Assert.False(requestLogged, "Request was logged when Activity logging was enabled.");
                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    WaitForTrue(() => activityStopLogged, TimeSpan.FromSeconds(1), "HttpRequestOut.Stop was not logged within 1 second timeout.");
                    Assert.False(exceptionLogged, "Exception was logged for successful request");
                    Assert.False(responseLogged, "Response was logged when Activity logging was enabled.");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#24
0
        public void SendAsync_ExpectedDiagnosticSynchronousExceptionActivityLogging()
        {
            if (IsCurlHandler)
            {
                // The only way to throw a synchronous exception for CurlHandler through
                // DiagnosticHandler is when the Request uri scheme is Https, and the
                // backend doesn't support SSL.
                return;
            }

            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool exceptionLogged           = false;
                bool activityStopLogged        = false;
                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.HttpRequestOut.Stop"))
                    {
                        Assert.NotNull(kvp.Value);
                        GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");
                        var requestStatus = GetPropertyValueFromAnonymousTypeInstance <TaskStatus>(kvp.Value, "RequestTaskStatus");
                        Assert.Equal(TaskStatus.Faulted, requestStatus);

                        activityStopLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Exception"))
                    {
                        Assert.NotNull(kvp.Value);
                        GetPropertyValueFromAnonymousTypeInstance <Exception>(kvp.Value, "Exception");

                        exceptionLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable();
                    using (HttpClientHandler handler = CreateHttpClientHandler(useSocketsHttpHandlerString))
                        using (HttpClient client = new HttpClient(handler))
                        {
                            // Set a https proxy.
                            handler.Proxy = new WebProxy($"https://{Guid.NewGuid()}.com", false);
                            HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, $"http://{Guid.NewGuid()}.com");

                            if (bool.Parse(useSocketsHttpHandlerString))
                            {
                                // Forces a synchronous exception for SocketsHttpHandler.
                                // SocketsHttpHandler only allow http scheme for proxies.

                                // We cannot use Assert.Throws<Exception>(() => { SendAsync(...); }) to verify the
                                // synchronous exception here, because DiagnosticsHandler SendAsync() method has async
                                // modifier, and returns Task. If the call is not awaited, the current test method will continue
                                // run before the call is completed, thus Assert.Throws() will not capture the exception.
                                // We need to wait for the Task to complete synchronously, to validate the exception.
                                Task sendTask = client.SendAsync(request);
                                Assert.True(sendTask.IsFaulted);
                                Assert.IsType <NotSupportedException>(sendTask.Exception.InnerException);
                            }
                            else
                            {
                                // Forces a synchronous exception for WinHttpHandler.
                                // WinHttpHandler will not allow (proxy != null && !UseCustomProxy).
                                handler.UseProxy = false;

                                // We cannot use Assert.Throws<Exception>(() => { SendAsync(...); }) to verify the
                                // synchronous exception here, because DiagnosticsHandler SendAsync() method has async
                                // modifier, and returns Task. If the call is not awaited, the current test method will continue
                                // run before the call is completed, thus Assert.Throws() will not capture the exception.
                                // We need to wait for the Task to complete synchronously, to validate the exception.
                                Task sendTask = client.SendAsync(request);
                                Assert.True(sendTask.IsFaulted);
                                Assert.IsType <InvalidOperationException>(sendTask.Exception.InnerException);
                            }
                        }
                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    WaitForTrue(() => activityStopLogged, TimeSpan.FromSeconds(1),
                                "Response with exception was not logged within 1 second timeout.");
                    Assert.True(exceptionLogged, "Exception was not logged");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }
示例#25
0
        public void SendAsync_ExpectedDiagnosticSourceLogging()
        {
            RemoteInvoke(useSocketsHttpHandlerString =>
            {
                bool requestLogged   = false;
                Guid requestGuid     = Guid.Empty;
                bool responseLogged  = false;
                Guid responseGuid    = Guid.Empty;
                bool exceptionLogged = false;
                bool activityLogged  = false;

                var diagnosticListenerObserver = new FakeDiagnosticListenerObserver(kvp =>
                {
                    if (kvp.Key.Equals("System.Net.Http.Request"))
                    {
                        Assert.NotNull(kvp.Value);
                        GetPropertyValueFromAnonymousTypeInstance <HttpRequestMessage>(kvp.Value, "Request");
                        requestGuid   = GetPropertyValueFromAnonymousTypeInstance <Guid>(kvp.Value, "LoggingRequestId");
                        requestLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Response"))
                    {
                        Assert.NotNull(kvp.Value);

                        GetPropertyValueFromAnonymousTypeInstance <HttpResponseMessage>(kvp.Value, "Response");
                        responseGuid      = GetPropertyValueFromAnonymousTypeInstance <Guid>(kvp.Value, "LoggingRequestId");
                        var requestStatus = GetPropertyValueFromAnonymousTypeInstance <TaskStatus>(kvp.Value, "RequestTaskStatus");
                        Assert.Equal(TaskStatus.RanToCompletion, requestStatus);

                        responseLogged = true;
                    }
                    else if (kvp.Key.Equals("System.Net.Http.Exception"))
                    {
                        exceptionLogged = true;
                    }
                    else if (kvp.Key.StartsWith("System.Net.Http.HttpRequestOut"))
                    {
                        activityLogged = true;
                    }
                });

                using (DiagnosticListener.AllListeners.Subscribe(diagnosticListenerObserver))
                {
                    diagnosticListenerObserver.Enable(s => !s.Contains("HttpRequestOut"));
                    using (HttpClient client = CreateHttpClient(useSocketsHttpHandlerString))
                    {
                        client.GetAsync(Configuration.Http.RemoteEchoServer).Result.Dispose();
                    }

                    Assert.True(requestLogged, "Request was not logged.");
                    // Poll with a timeout since logging response is not synchronized with returning a response.
                    WaitForTrue(() => responseLogged, TimeSpan.FromSeconds(1), "Response was not logged within 1 second timeout.");
                    Assert.Equal(requestGuid, responseGuid);
                    Assert.False(exceptionLogged, "Exception was logged for successful request");
                    Assert.False(activityLogged, "HttpOutReq was logged while HttpOutReq logging was disabled");
                    diagnosticListenerObserver.Disable();
                }

                return(SuccessExitCode);
            }, UseSocketsHttpHandler.ToString()).Dispose();
        }