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(); }
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(); }
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(); }
[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(); }
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(); }
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(); }
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(); }
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 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(); }
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(); }
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); } }
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); }
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(); }
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(); }
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(); }
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(); }
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. } }
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. } }
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(); }
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(); }
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(); }