1 // Licensed to the .NET Foundation under one or more agreements.
2 // The .NET Foundation licenses this file to you under the MIT license.
3 // See the LICENSE file in the project root for more information.
5 using System.Collections.Generic;
6 using System.Diagnostics;
7 using System.Net.Test.Common;
8 using System.Runtime.InteropServices;
10 using System.Threading.Tasks;
11 using Microsoft.DotNet.RemoteExecutor;
13 using Xunit.Abstractions;
15 namespace System.Net.Http.Functional.Tests
17 using Configuration = System.Net.Test.Common.Configuration;
19 public abstract class HttpClientHandler_DefaultProxyCredentials_Test : HttpClientHandlerTestBase
21 public HttpClientHandler_DefaultProxyCredentials_Test(ITestOutputHelper output) : base(output) { }
24 public void Default_Get_Null()
26 using (HttpClientHandler handler = CreateHttpClientHandler())
28 Assert.Null(handler.DefaultProxyCredentials);
33 public void SetGet_Roundtrips()
35 using (HttpClientHandler handler = CreateHttpClientHandler())
37 var creds = new NetworkCredential("username", "password", "domain");
39 handler.DefaultProxyCredentials = null;
40 Assert.Null(handler.DefaultProxyCredentials);
42 handler.DefaultProxyCredentials = creds;
43 Assert.Same(creds, handler.DefaultProxyCredentials);
45 handler.DefaultProxyCredentials = CredentialCache.DefaultCredentials;
46 Assert.Same(CredentialCache.DefaultCredentials, handler.DefaultProxyCredentials);
51 public async Task ProxyExplicitlyProvided_DefaultCredentials_Ignored()
53 var explicitProxyCreds = new NetworkCredential("rightusername", "rightpassword");
54 var defaultSystemProxyCreds = new NetworkCredential("wrongusername", "wrongpassword");
55 string expectCreds = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes($"{explicitProxyCreds.UserName}:{explicitProxyCreds.Password}"));
57 await LoopbackServer.CreateClientAndServerAsync(async proxyUrl =>
59 using (HttpClientHandler handler = CreateHttpClientHandler())
60 using (HttpClient client = CreateHttpClient(handler))
62 handler.Proxy = new UseSpecifiedUriWebProxy(proxyUrl, explicitProxyCreds);
63 handler.DefaultProxyCredentials = defaultSystemProxyCreds;
64 using (HttpResponseMessage response = await client.GetAsync("http://notatrealserver.com/")) // URL does not matter
66 Assert.Equal(HttpStatusCode.OK, response.StatusCode);
71 await server.AcceptConnectionSendResponseAndCloseAsync(
72 HttpStatusCode.ProxyAuthenticationRequired, "Proxy-Authenticate: Basic\r\n");
74 List<string> headers = await server.AcceptConnectionSendResponseAndCloseAsync(HttpStatusCode.OK);
75 Assert.Equal(expectCreds, LoopbackServer.GetRequestHeaderValue(headers, "Proxy-Authorization"));
79 [ActiveIssue("https://github.com/dotnet/corefx/issues/42323")]
80 [OuterLoop("Uses external server")]
81 [PlatformSpecific(TestPlatforms.AnyUnix)] // The default proxy is resolved via WinINet on Windows.
85 public async Task ProxySetViaEnvironmentVariable_DefaultProxyCredentialsUsed(bool useProxy)
87 const string ExpectedUsername = "rightusername";
88 const string ExpectedPassword = "rightpassword";
89 LoopbackServer.Options options = new LoopbackServer.Options { IsProxy = true, Username = ExpectedUsername, Password = ExpectedPassword };
91 await LoopbackServer.CreateServerAsync(async (proxyServer, proxyUri) =>
93 // SocketsHttpHandler can read a default proxy from the http_proxy environment variable. Ensure that when it does,
94 // our default proxy credentials are used. To avoid messing up anything else in this process, we run the
95 // test in another process.
96 var psi = new ProcessStartInfo();
97 Task<List<string>> proxyTask = null;
101 proxyTask = proxyServer.AcceptConnectionPerformAuthenticationAndCloseAsync("Proxy-Authenticate: Basic realm=\"NetCore\"\r\n");
102 psi.Environment.Add("http_proxy", $"http://{proxyUri.Host}:{proxyUri.Port}");
105 RemoteExecutor.Invoke(async (useProxyString, useHttp2String) =>
107 using (HttpClientHandler handler = CreateHttpClientHandler(useHttp2String))
108 using (HttpClient client = CreateHttpClient(handler, useHttp2String))
110 var creds = new NetworkCredential(ExpectedUsername, ExpectedPassword);
111 handler.DefaultProxyCredentials = creds;
112 handler.UseProxy = bool.Parse(useProxyString);
114 HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer);
115 // Correctness of user and password is done in server part.
116 Assert.True(response.StatusCode == HttpStatusCode.OK);
118 }, useProxy.ToString(), UseHttp2.ToString(), new RemoteInvokeOptions { StartInfo = psi }).Dispose();
126 // The purpose of this test is mainly to validate the .NET Framework OOB System.Net.Http implementation
127 // since it has an underlying dependency to WebRequest. While .NET Core implementations of System.Net.Http
128 // are not using any WebRequest code, the test is still useful to validate correctness.
129 [OuterLoop("Uses external server")]
131 public async Task ProxyNotExplicitlyProvided_DefaultCredentialsSet_DefaultWebProxySetToNull_Success()
133 WebRequest.DefaultWebProxy = null;
135 using (HttpClientHandler handler = CreateHttpClientHandler())
136 using (HttpClient client = CreateHttpClient(handler))
138 handler.DefaultProxyCredentials = new NetworkCredential("UsernameNotUsed", "PasswordNotUsed");
139 HttpResponseMessage response = await client.GetAsync(Configuration.Http.RemoteEchoServer);
141 Assert.Equal(HttpStatusCode.OK, response.StatusCode);